mirror of
https://github.com/ton-blockchain/ton
synced 2025-02-14 12:12:21 +00:00
Add overlay certificate checks
This commit is contained in:
parent
9e9351903a
commit
678a8a6a13
17 changed files with 232 additions and 62 deletions
|
@ -486,7 +486,7 @@ void CatChainReceiverImpl::start_up() {
|
|||
}
|
||||
td::actor::send_closure(overlay_manager_, &overlay::Overlays::create_private_overlay,
|
||||
get_source(local_idx_)->get_adnl_id(), overlay_full_id_.clone(), std::move(ids),
|
||||
make_callback(), overlay::OverlayPrivacyRules{0, std::move(root_keys)});
|
||||
make_callback(), overlay::OverlayPrivacyRules{0, 0, std::move(root_keys)});
|
||||
|
||||
CHECK(root_block_);
|
||||
|
||||
|
|
|
@ -17,8 +17,14 @@
|
|||
Copyright 2017-2020 Telegram Systems LLP
|
||||
*/
|
||||
#include "overlay-broadcast.hpp"
|
||||
#include "adnl/adnl-node-id.hpp"
|
||||
#include "common/util.h"
|
||||
#include "overlay.hpp"
|
||||
#include "keys/encryptor.h"
|
||||
#include "td/actor/PromiseFuture.h"
|
||||
#include "td/actor/actor.h"
|
||||
#include "td/utils/Status.h"
|
||||
#include "td/utils/port/Stat.h"
|
||||
|
||||
namespace ton {
|
||||
|
||||
|
@ -33,7 +39,13 @@ td::Status BroadcastSimple::check_duplicate() {
|
|||
}
|
||||
|
||||
td::Status BroadcastSimple::check_source() {
|
||||
return overlay_->check_source_eligible(source_, cert_.get(), data_size());
|
||||
auto r = overlay_->check_source_eligible(source_, cert_.get(), data_size(), false);
|
||||
if (r == BroadcastCheckResult::Forbidden) {
|
||||
return td::Status::Error(ErrorCode::error, "broadcast is forbidden");
|
||||
}
|
||||
|
||||
is_valid_ = r == BroadcastCheckResult::Allowed;
|
||||
return td::Status::OK();
|
||||
}
|
||||
|
||||
td::BufferSlice BroadcastSimple::to_sign() {
|
||||
|
@ -66,6 +78,14 @@ td::Status BroadcastSimple::distribute() {
|
|||
return td::Status::OK();
|
||||
}
|
||||
|
||||
void BroadcastSimple::broadcast_checked(td::Result<td::Unit> R) {
|
||||
if (R.is_error()) {
|
||||
return;
|
||||
}
|
||||
is_valid_ = true;
|
||||
run_continue().ignore();
|
||||
}
|
||||
|
||||
tl_object_ptr<ton_api::overlay_broadcast> BroadcastSimple::tl() const {
|
||||
return create_tl_object<ton_api::overlay_broadcast>(source_.tl(), cert_ ? cert_->tl() : Certificate::empty_tl(),
|
||||
flags_, data_.clone(), date_, signature_.clone());
|
||||
|
@ -75,6 +95,25 @@ td::BufferSlice BroadcastSimple::serialize() {
|
|||
return serialize_tl_object(tl(), true);
|
||||
}
|
||||
|
||||
td::Status BroadcastSimple::run_continue() {
|
||||
TRY_STATUS(distribute());
|
||||
deliver();
|
||||
return td::Status::OK();
|
||||
}
|
||||
|
||||
td::Status BroadcastSimple::run() {
|
||||
TRY_STATUS(run_checks());
|
||||
if (!is_valid_) {
|
||||
auto P = td::PromiseCreator::lambda(
|
||||
[id = broadcast_hash_, overlay_id = actor_id(overlay_)](td::Result<td::Unit> R) mutable {
|
||||
td::actor::send_closure(std::move(overlay_id), &OverlayImpl::broadcast_checked, id, std::move(R));
|
||||
});
|
||||
overlay_->check_broadcast(source_.compute_short_id(), data_.clone(), std::move(P));
|
||||
return td::Status::OK();
|
||||
}
|
||||
return run_continue();
|
||||
}
|
||||
|
||||
td::Status BroadcastSimple::create(OverlayImpl *overlay, tl_object_ptr<ton_api::overlay_broadcast> broadcast) {
|
||||
auto src = PublicKey{broadcast->src_};
|
||||
auto data_hash = sha256_bits256(broadcast->data_.as_slice());
|
||||
|
@ -86,7 +125,7 @@ td::Status BroadcastSimple::create(OverlayImpl *overlay, tl_object_ptr<ton_api::
|
|||
|
||||
auto B = std::make_unique<BroadcastSimple>(broadcast_hash, src, std::move(cert), broadcast->flags_,
|
||||
std::move(broadcast->data_), broadcast->date_,
|
||||
std::move(broadcast->signature_), overlay);
|
||||
std::move(broadcast->signature_), false, overlay);
|
||||
TRY_STATUS(B->run());
|
||||
overlay->register_simple_broadcast(std::move(B));
|
||||
return td::Status::OK();
|
||||
|
@ -100,7 +139,7 @@ td::Status BroadcastSimple::create_new(td::actor::ActorId<OverlayImpl> overlay,
|
|||
auto date = static_cast<td::uint32>(td::Clocks::system());
|
||||
|
||||
auto B = std::make_unique<BroadcastSimple>(broadcast_hash, PublicKey{}, nullptr, flags, std::move(data), date,
|
||||
td::BufferSlice{}, nullptr);
|
||||
td::BufferSlice{}, false, nullptr);
|
||||
|
||||
auto to_sign = B->to_sign();
|
||||
auto P = td::PromiseCreator::lambda(
|
||||
|
|
|
@ -18,9 +18,16 @@
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include "adnl/adnl-local-id.h"
|
||||
#include "adnl/adnl-node-id.hpp"
|
||||
#include "auto/tl/ton_api.h"
|
||||
#include "common/refcnt.hpp"
|
||||
#include "overlay/overlay.h"
|
||||
#include "td/actor/PromiseFuture.h"
|
||||
#include "td/utils/List.h"
|
||||
#include "td/utils/Status.h"
|
||||
#include "td/utils/buffer.h"
|
||||
#include "td/utils/common.h"
|
||||
|
||||
namespace ton {
|
||||
|
||||
|
@ -38,6 +45,7 @@ class BroadcastSimple : public td::ListNode {
|
|||
td::BufferSlice data_;
|
||||
td::uint32 date_;
|
||||
td::BufferSlice signature_;
|
||||
bool is_valid_{false};
|
||||
|
||||
OverlayImpl *overlay_;
|
||||
|
||||
|
@ -52,7 +60,7 @@ class BroadcastSimple : public td::ListNode {
|
|||
|
||||
public:
|
||||
BroadcastSimple(Overlay::BroadcastHash broadcast_hash, PublicKey source, std::shared_ptr<Certificate> cert,
|
||||
td::uint32 flags, td::BufferSlice data, td::uint32 date, td::BufferSlice signature,
|
||||
td::uint32 flags, td::BufferSlice data, td::uint32 date, td::BufferSlice signature, bool is_valid,
|
||||
OverlayImpl *overlay)
|
||||
: broadcast_hash_(broadcast_hash)
|
||||
, source_(std::move(source))
|
||||
|
@ -61,6 +69,7 @@ class BroadcastSimple : public td::ListNode {
|
|||
, data_(std::move(data))
|
||||
, date_(date)
|
||||
, signature_(std::move(signature))
|
||||
, is_valid_(is_valid)
|
||||
, overlay_(overlay) {
|
||||
}
|
||||
|
||||
|
@ -80,17 +89,14 @@ class BroadcastSimple : public td::ListNode {
|
|||
}
|
||||
void deliver();
|
||||
|
||||
td::Status run() {
|
||||
TRY_STATUS(run_checks());
|
||||
TRY_STATUS(distribute());
|
||||
deliver();
|
||||
return td::Status::OK();
|
||||
}
|
||||
td::Status run();
|
||||
td::Status run_continue();
|
||||
|
||||
tl_object_ptr<ton_api::overlay_broadcast> tl() const;
|
||||
td::BufferSlice serialize();
|
||||
|
||||
void update_overlay(OverlayImpl *overlay);
|
||||
void broadcast_checked(td::Result<td::Unit> R);
|
||||
|
||||
static td::Status create(OverlayImpl *overlay, tl_object_ptr<ton_api::overlay_broadcast> broadcast);
|
||||
static td::Status create_new(td::actor::ActorId<OverlayImpl> overlay, td::actor::ActorId<keyring::Keyring> keyring,
|
||||
|
|
|
@ -54,7 +54,16 @@ td::Status OverlayFecBroadcastPart::check_duplicate() {
|
|||
}
|
||||
|
||||
td::Status OverlayFecBroadcastPart::check_source() {
|
||||
TRY_STATUS(overlay_->check_source_eligible(source_, cert_.get(), broadcast_size_));
|
||||
auto r = overlay_->check_source_eligible(source_, cert_.get(), broadcast_size_, true);
|
||||
if (r == BroadcastCheckResult::Forbidden) {
|
||||
return td::Status::Error(ErrorCode::error, "broadcast is forbidden");
|
||||
}
|
||||
|
||||
// FIXME
|
||||
if (r == BroadcastCheckResult::NeedCheck) {
|
||||
return td::Status::Error(ErrorCode::error, "broadcast is forbidden");
|
||||
}
|
||||
|
||||
if (bcast_) {
|
||||
TRY_STATUS(bcast_->is_eligible_sender(source_));
|
||||
}
|
||||
|
|
|
@ -185,6 +185,9 @@ class BroadcastFec : public td::ListNode {
|
|||
}
|
||||
}
|
||||
|
||||
void broadcast_checked(td::Result<td::Unit> R) {
|
||||
}
|
||||
|
||||
private:
|
||||
bool ready_ = false;
|
||||
|
||||
|
@ -311,4 +314,3 @@ class OverlayFecBroadcastPart : public td::ListNode {
|
|||
} // namespace overlay
|
||||
|
||||
} // namespace ton
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
Copyright 2017-2020 Telegram Systems LLP
|
||||
*/
|
||||
#include "overlay-manager.h"
|
||||
#include "auto/tl/ton_api.h"
|
||||
#include "overlay.h"
|
||||
|
||||
#include "adnl/utils.hpp"
|
||||
|
@ -268,17 +269,21 @@ void OverlayManager::save_to_db(adnl::AdnlNodeIdShort local_id, OverlayIdShort o
|
|||
db_.set(key, create_serialize_tl_object<ton_api::overlay_db_nodes>(std::move(obj)));
|
||||
}
|
||||
|
||||
Certificate::Certificate(PublicKey issued_by, td::int32 expire_at, td::uint32 max_size, td::BufferSlice signature)
|
||||
Certificate::Certificate(PublicKey issued_by, td::int32 expire_at, td::uint32 max_size, td::uint32 flags,
|
||||
td::BufferSlice signature)
|
||||
: issued_by_(issued_by)
|
||||
, expire_at_(expire_at)
|
||||
, max_size_(max_size)
|
||||
, flags_(flags)
|
||||
, signature_(td::SharedSlice(signature.as_slice())) {
|
||||
}
|
||||
|
||||
Certificate::Certificate(PublicKeyHash issued_by, td::int32 expire_at, td::uint32 max_size, td::BufferSlice signature)
|
||||
Certificate::Certificate(PublicKeyHash issued_by, td::int32 expire_at, td::uint32 max_size, td::uint32 flags,
|
||||
td::BufferSlice signature)
|
||||
: issued_by_(issued_by)
|
||||
, expire_at_(expire_at)
|
||||
, max_size_(max_size)
|
||||
, flags_(flags)
|
||||
, signature_(td::SharedSlice(signature.as_slice())) {
|
||||
}
|
||||
|
||||
|
@ -290,9 +295,19 @@ void Certificate::set_issuer(PublicKey issuer) {
|
|||
issued_by_ = issuer;
|
||||
}
|
||||
|
||||
constexpr td::uint32 cert_default_flags(td::uint32 max_size) {
|
||||
return (max_size > Overlays::max_simple_broadcast_size() ? CertificateFlags::AllowFec : 0) |
|
||||
CertificateFlags::Trusted;
|
||||
}
|
||||
|
||||
td::BufferSlice Certificate::to_sign(OverlayIdShort overlay_id, PublicKeyHash issued_to) const {
|
||||
return create_serialize_tl_object<ton_api::overlay_certificateId>(overlay_id.tl(), issued_to.tl(), expire_at_,
|
||||
max_size_);
|
||||
if (flags_ == cert_default_flags(max_size_)) {
|
||||
return create_serialize_tl_object<ton_api::overlay_certificateId>(overlay_id.tl(), issued_to.tl(), expire_at_,
|
||||
max_size_);
|
||||
} else {
|
||||
return create_serialize_tl_object<ton_api::overlay_certificateIdV2>(overlay_id.tl(), issued_to.tl(), expire_at_,
|
||||
max_size_, flags_);
|
||||
}
|
||||
}
|
||||
|
||||
const PublicKeyHash Certificate::issuer_hash() const {
|
||||
|
@ -307,32 +322,48 @@ const PublicKey &Certificate::issuer() const {
|
|||
|
||||
td::Result<std::shared_ptr<Certificate>> Certificate::create(tl_object_ptr<ton_api::overlay_Certificate> cert) {
|
||||
std::shared_ptr<Certificate> res;
|
||||
ton_api::downcast_call(*cert.get(), td::overloaded([&](ton_api::overlay_emptyCertificate &obj) { res = nullptr; },
|
||||
[&](ton_api::overlay_certificate &obj) {
|
||||
res = std::make_shared<Certificate>(
|
||||
PublicKey{obj.issued_by_}, obj.expire_at_,
|
||||
static_cast<td::uint32>(obj.max_size_),
|
||||
std::move(obj.signature_));
|
||||
}));
|
||||
ton_api::downcast_call(*cert.get(),
|
||||
td::overloaded([&](ton_api::overlay_emptyCertificate &obj) { res = nullptr; },
|
||||
[&](ton_api::overlay_certificate &obj) {
|
||||
res = std::make_shared<Certificate>(PublicKey{obj.issued_by_}, obj.expire_at_,
|
||||
static_cast<td::uint32>(obj.max_size_),
|
||||
cert_default_flags(obj.max_size_),
|
||||
std::move(obj.signature_));
|
||||
},
|
||||
[&](ton_api::overlay_certificateV2 &obj) {
|
||||
res = std::make_shared<Certificate>(PublicKey{obj.issued_by_}, obj.expire_at_,
|
||||
static_cast<td::uint32>(obj.max_size_),
|
||||
static_cast<td::uint32>(obj.flags_),
|
||||
std::move(obj.signature_));
|
||||
}));
|
||||
return std::move(res);
|
||||
}
|
||||
|
||||
td::Status Certificate::check(PublicKeyHash node, OverlayIdShort overlay_id, td::int32 unix_time,
|
||||
td::uint32 size) const {
|
||||
BroadcastCheckResult Certificate::check(PublicKeyHash node, OverlayIdShort overlay_id, td::int32 unix_time,
|
||||
td::uint32 size, bool is_fec) const {
|
||||
if (size > max_size_) {
|
||||
return td::Status::Error(ErrorCode::protoviolation, "too big broadcast size");
|
||||
return BroadcastCheckResult::Forbidden;
|
||||
}
|
||||
if (unix_time > expire_at_) {
|
||||
return td::Status::Error(ErrorCode::protoviolation, "too old certificate");
|
||||
return BroadcastCheckResult::Forbidden;
|
||||
}
|
||||
if (is_fec && !(flags_ & CertificateFlags::AllowFec)) {
|
||||
return BroadcastCheckResult::Forbidden;
|
||||
}
|
||||
|
||||
TRY_RESULT(E, issued_by_.get<PublicKey>().create_encryptor());
|
||||
auto R1 = issued_by_.get<PublicKey>().create_encryptor();
|
||||
if (R1.is_error()) {
|
||||
return BroadcastCheckResult::Forbidden;
|
||||
}
|
||||
auto E = R1.move_as_ok();
|
||||
|
||||
auto B = to_sign(overlay_id, node);
|
||||
|
||||
TRY_STATUS(E->check_signature(B.as_slice(), signature_.as_slice()));
|
||||
if (E->check_signature(B.as_slice(), signature_.as_slice()).is_error()) {
|
||||
return BroadcastCheckResult::Forbidden;
|
||||
}
|
||||
|
||||
return td::Status::OK();
|
||||
return (flags_ & CertificateFlags::Trusted) ? BroadcastCheckResult::Allowed : BroadcastCheckResult::NeedCheck;
|
||||
}
|
||||
|
||||
tl_object_ptr<ton_api::overlay_Certificate> Certificate::tl() const {
|
||||
|
|
|
@ -391,25 +391,21 @@ td::Status OverlayImpl::check_date(td::uint32 date) {
|
|||
return td::Status::OK();
|
||||
}
|
||||
|
||||
td::Status OverlayImpl::check_source_eligible(PublicKey source, const Certificate *cert, td::uint32 size) {
|
||||
BroadcastCheckResult OverlayImpl::check_source_eligible(PublicKey source, const Certificate *cert, td::uint32 size,
|
||||
bool is_fec) {
|
||||
if (size == 0) {
|
||||
return td::Status::Error(ErrorCode::protoviolation, "empty broadcast");
|
||||
return BroadcastCheckResult::Forbidden;
|
||||
}
|
||||
auto short_id = source.compute_short_id();
|
||||
|
||||
auto r = rules_.max_size(source.compute_short_id());
|
||||
if (r >= size) {
|
||||
return td::Status::OK();
|
||||
auto r = rules_.check_rules(source.compute_short_id(), size, is_fec);
|
||||
if (!cert || r == BroadcastCheckResult::Allowed) {
|
||||
return r;
|
||||
}
|
||||
if (!cert) {
|
||||
return td::Status::Error(ErrorCode::protoviolation, "source is not eligible");
|
||||
}
|
||||
TRY_STATUS(cert->check(short_id, overlay_id_, static_cast<td::int32>(td::Clocks::system()), size));
|
||||
auto issuer_short = cert->issuer_hash();
|
||||
if (rules_.max_size(issuer_short) < size) {
|
||||
return td::Status::Error(ErrorCode::protoviolation, "bad certificate");
|
||||
}
|
||||
return td::Status::OK();
|
||||
|
||||
auto r2 = cert->check(short_id, overlay_id_, static_cast<td::int32>(td::Clocks::system()), size, is_fec);
|
||||
r2 = broadcast_check_result_min(r2, rules_.check_rules(cert->issuer_hash(), size, is_fec));
|
||||
return broadcast_check_result_max(r, r2);
|
||||
}
|
||||
|
||||
td::Status OverlayImpl::check_delivered(BroadcastHash hash) {
|
||||
|
@ -539,6 +535,25 @@ void OverlayImpl::set_privacy_rules(OverlayPrivacyRules rules) {
|
|||
rules_ = std::move(rules);
|
||||
}
|
||||
|
||||
void OverlayImpl::check_broadcast(PublicKeyHash src, td::BufferSlice data, td::Promise<td::Unit> promise) {
|
||||
callback_->check_broadcast(src, overlay_id_, std::move(data), std::move(promise));
|
||||
}
|
||||
|
||||
void OverlayImpl::broadcast_checked(Overlay::BroadcastHash hash, td::Result<td::Unit> R) {
|
||||
{
|
||||
auto it = broadcasts_.find(hash);
|
||||
if (it != broadcasts_.end()) {
|
||||
it->second->broadcast_checked(std::move(R));
|
||||
}
|
||||
}
|
||||
{
|
||||
auto it = fec_broadcasts_.find(hash);
|
||||
if (it != fec_broadcasts_.end()) {
|
||||
it->second->broadcast_checked(std::move(R));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace overlay
|
||||
|
||||
} // namespace ton
|
||||
|
|
|
@ -144,9 +144,12 @@ class OverlayImpl : public Overlay {
|
|||
void print(td::StringBuilder &sb) override;
|
||||
|
||||
td::Status check_date(td::uint32 date);
|
||||
td::Status check_source_eligible(PublicKey source, const Certificate *cert, td::uint32 size);
|
||||
BroadcastCheckResult check_source_eligible(PublicKey source, const Certificate *cert, td::uint32 size, bool is_fec);
|
||||
td::Status check_delivered(BroadcastHash hash);
|
||||
|
||||
void broadcast_checked(Overlay::BroadcastHash hash, td::Result<td::Unit> R);
|
||||
void check_broadcast(PublicKeyHash src, td::BufferSlice data, td::Promise<td::Unit> promise);
|
||||
|
||||
BroadcastFec *get_fec_broadcast(BroadcastHash hash);
|
||||
void register_fec_broadcast(std::unique_ptr<BroadcastFec> bcast);
|
||||
void register_simple_broadcast(std::unique_ptr<BroadcastSimple> bcast);
|
||||
|
|
|
@ -21,7 +21,11 @@
|
|||
#include "adnl/adnl.h"
|
||||
#include "dht/dht.h"
|
||||
|
||||
#include "td/actor/PromiseFuture.h"
|
||||
#include "td/actor/actor.h"
|
||||
#include "td/utils/Status.h"
|
||||
#include "td/utils/buffer.h"
|
||||
#include "td/utils/common.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
|
@ -80,41 +84,64 @@ class OverlayIdFull {
|
|||
td::BufferSlice name_;
|
||||
};
|
||||
|
||||
struct CertificateFlags {
|
||||
enum Values : td::uint32 { AllowFec = 1, Trusted = 2 };
|
||||
};
|
||||
|
||||
enum BroadcastCheckResult { Forbidden = 1, NeedCheck = 2, Allowed = 3 };
|
||||
|
||||
inline BroadcastCheckResult broadcast_check_result_max(BroadcastCheckResult l, BroadcastCheckResult r) {
|
||||
return static_cast<BroadcastCheckResult>(std::max(static_cast<td::int32>(l), static_cast<td::int32>(r)));
|
||||
}
|
||||
inline BroadcastCheckResult broadcast_check_result_min(BroadcastCheckResult l, BroadcastCheckResult r) {
|
||||
return static_cast<BroadcastCheckResult>(std::min(static_cast<td::int32>(l), static_cast<td::int32>(r)));
|
||||
}
|
||||
|
||||
class OverlayPrivacyRules {
|
||||
public:
|
||||
OverlayPrivacyRules() {
|
||||
}
|
||||
OverlayPrivacyRules(td::uint32 size) : max_unath_size_(size) {
|
||||
}
|
||||
OverlayPrivacyRules(td::uint32 max_size, std::map<PublicKeyHash, td::uint32> authorized_keys)
|
||||
: max_unath_size_(max_size), authorized_keys_(std::move(authorized_keys)) {
|
||||
OverlayPrivacyRules(td::uint32 max_size, td::uint32 flags, std::map<PublicKeyHash, td::uint32> authorized_keys)
|
||||
: max_unath_size_(max_size), flags_(flags), authorized_keys_(std::move(authorized_keys)) {
|
||||
}
|
||||
|
||||
td::uint32 max_size(PublicKeyHash hash) {
|
||||
BroadcastCheckResult check_rules(PublicKeyHash hash, td::uint32 size, bool is_fec) {
|
||||
auto it = authorized_keys_.find(hash);
|
||||
if (it == authorized_keys_.end()) {
|
||||
return max_unath_size_;
|
||||
if (size > max_unath_size_) {
|
||||
return BroadcastCheckResult::Forbidden;
|
||||
}
|
||||
if (!(flags_ & CertificateFlags::AllowFec) && is_fec) {
|
||||
return BroadcastCheckResult::Forbidden;
|
||||
}
|
||||
return (flags_ & CertificateFlags::Trusted) ? BroadcastCheckResult::Allowed : BroadcastCheckResult::NeedCheck;
|
||||
} else {
|
||||
return it->second;
|
||||
return it->second >= size ? BroadcastCheckResult::Allowed : BroadcastCheckResult::Forbidden;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
td::uint32 max_unath_size_{0};
|
||||
td::uint32 flags_{0};
|
||||
std::map<PublicKeyHash, td::uint32> authorized_keys_;
|
||||
};
|
||||
|
||||
class Certificate {
|
||||
public:
|
||||
Certificate(PublicKeyHash issued_by, td::int32 expire_at, td::uint32 max_size, td::BufferSlice signature);
|
||||
Certificate(PublicKey issued_by, td::int32 expire_at, td::uint32 max_size, td::BufferSlice signature);
|
||||
Certificate(PublicKeyHash issued_by, td::int32 expire_at, td::uint32 max_size, td::uint32 flags,
|
||||
td::BufferSlice signature);
|
||||
Certificate(PublicKey issued_by, td::int32 expire_at, td::uint32 max_size, td::uint32 flags,
|
||||
td::BufferSlice signature);
|
||||
Certificate() {
|
||||
}
|
||||
void set_signature(td::BufferSlice signature);
|
||||
void set_issuer(PublicKey issuer);
|
||||
td::BufferSlice to_sign(OverlayIdShort overlay_id, PublicKeyHash issued_to) const;
|
||||
|
||||
td::Status check(PublicKeyHash node, OverlayIdShort overlay_id, td::int32 unix_time, td::uint32 size) const;
|
||||
BroadcastCheckResult check(PublicKeyHash node, OverlayIdShort overlay_id, td::int32 unix_time, td::uint32 size,
|
||||
bool is_fec) const;
|
||||
tl_object_ptr<ton_api::overlay_Certificate> tl() const;
|
||||
const PublicKey &issuer() const;
|
||||
const PublicKeyHash issuer_hash() const;
|
||||
|
@ -126,6 +153,7 @@ class Certificate {
|
|||
td::Variant<PublicKey, PublicKeyHash> issued_by_;
|
||||
td::int32 expire_at_;
|
||||
td::uint32 max_size_;
|
||||
td::uint32 flags_;
|
||||
td::SharedSlice signature_;
|
||||
};
|
||||
|
||||
|
@ -137,6 +165,10 @@ class Overlays : public td::actor::Actor {
|
|||
virtual void receive_query(adnl::AdnlNodeIdShort src, OverlayIdShort overlay_id, td::BufferSlice data,
|
||||
td::Promise<td::BufferSlice> promise) = 0;
|
||||
virtual void receive_broadcast(PublicKeyHash src, OverlayIdShort overlay_id, td::BufferSlice data) = 0;
|
||||
virtual void check_broadcast(PublicKeyHash src, OverlayIdShort overlay_id, td::BufferSlice data,
|
||||
td::Promise<td::Unit> promise) {
|
||||
promise.set_value(td::Unit());
|
||||
}
|
||||
virtual ~Callback() = default;
|
||||
};
|
||||
|
||||
|
|
|
@ -219,9 +219,11 @@ overlay.broadcastFec.partId broadcast_hash:int256 data_hash:int256 seqno:int = o
|
|||
overlay.broadcast.toSign hash:int256 date:int = overlay.broadcast.ToSign;
|
||||
|
||||
overlay.certificate issued_by:PublicKey expire_at:int max_size:int signature:bytes = overlay.Certificate;
|
||||
overlay.certificateV2 issued_by:PublicKey expire_at:int max_size:int flags:int signature:bytes = overlay.Certificate;
|
||||
overlay.emptyCertificate = overlay.Certificate;
|
||||
|
||||
overlay.certificateId overlay_id:int256 node:int256 expire_at:int max_size:int = overlay.CertificateId;
|
||||
overlay.certificateIdV2 overlay_id:int256 node:int256 expire_at:int max_size:int flags:int = overlay.CertificateId;
|
||||
|
||||
overlay.unicast data:bytes = overlay.Broadcast;
|
||||
overlay.broadcast src:PublicKey certificate:overlay.Certificate flags:int data:bytes date:int signature:bytes = overlay.Broadcast;
|
||||
|
|
Binary file not shown.
|
@ -16,6 +16,8 @@
|
|||
|
||||
Copyright 2017-2020 Telegram Systems LLP
|
||||
*/
|
||||
#include "auto/tl/ton_api.h"
|
||||
#include "overlays.h"
|
||||
#include "td/utils/SharedSlice.h"
|
||||
#include "full-node-shard.hpp"
|
||||
#include "full-node-shard-queries.hpp"
|
||||
|
@ -79,6 +81,10 @@ void FullNodeShardImpl::create_overlay() {
|
|||
void receive_broadcast(PublicKeyHash src, overlay::OverlayIdShort overlay_id, td::BufferSlice data) override {
|
||||
td::actor::send_closure(node_, &FullNodeShardImpl::receive_broadcast, src, std::move(data));
|
||||
}
|
||||
void check_broadcast(PublicKeyHash src, overlay::OverlayIdShort overlay_id, td::BufferSlice data,
|
||||
td::Promise<td::Unit> promise) override {
|
||||
td::actor::send_closure(node_, &FullNodeShardImpl::check_broadcast, src, std::move(data), std::move(promise));
|
||||
}
|
||||
Callback(td::actor::ActorId<FullNodeShardImpl> node) : node_(node) {
|
||||
}
|
||||
|
||||
|
@ -95,6 +101,17 @@ void FullNodeShardImpl::create_overlay() {
|
|||
}
|
||||
}
|
||||
|
||||
void FullNodeShardImpl::check_broadcast(PublicKeyHash src, td::BufferSlice broadcast, td::Promise<td::Unit> promise) {
|
||||
auto B = fetch_tl_object<ton_api::tonNode_externalMessageBroadcast>(std::move(broadcast), true);
|
||||
if (B.is_error()) {
|
||||
return promise.set_error(B.move_as_error_prefix("failed to parse external message broadcast: "));
|
||||
}
|
||||
|
||||
auto q = B.move_as_ok();
|
||||
td::actor::send_closure(validator_manager_, &ValidatorManagerInterface::check_external_message,
|
||||
std::move(q->message_->data_), std::move(promise));
|
||||
}
|
||||
|
||||
void FullNodeShardImpl::update_adnl_id(adnl::AdnlNodeIdShort adnl_id, td::Promise<td::Unit> promise) {
|
||||
td::actor::send_closure(overlays_, &ton::overlay::Overlays::delete_overlay, adnl_id_, overlay_id_);
|
||||
adnl_id_ = adnl_id;
|
||||
|
@ -804,8 +821,9 @@ void FullNodeShardImpl::sign_new_certificate(PublicKeyHash sign_by) {
|
|||
return;
|
||||
}
|
||||
|
||||
ton::overlay::Certificate cert{sign_by, static_cast<td::int32>(td::Clocks::system() + 3600),
|
||||
overlay::Overlays::max_fec_broadcast_size(), td::BufferSlice{}};
|
||||
ton::overlay::Certificate cert{
|
||||
sign_by, static_cast<td::int32>(td::Clocks::system() + 3600), overlay::Overlays::max_fec_broadcast_size(),
|
||||
overlay::CertificateFlags::Trusted | overlay::CertificateFlags::AllowFec, td::BufferSlice{}};
|
||||
auto to_sign = cert.to_sign(overlay_id_, local_id_);
|
||||
|
||||
auto P = td::PromiseCreator::lambda(
|
||||
|
@ -845,7 +863,7 @@ void FullNodeShardImpl::update_validators(std::vector<PublicKeyHash> public_key_
|
|||
authorized_keys.emplace(key, overlay::Overlays::max_fec_broadcast_size());
|
||||
}
|
||||
|
||||
rules_ = overlay::OverlayPrivacyRules{1 << 14, std::move(authorized_keys)};
|
||||
rules_ = overlay::OverlayPrivacyRules{1 << 14, 0, std::move(authorized_keys)};
|
||||
td::actor::send_closure(overlays_, &overlay::Overlays::set_privacy_rules, adnl_id_, overlay_id_, rules_);
|
||||
|
||||
if (update_cert) {
|
||||
|
@ -949,8 +967,7 @@ void FullNodeShardImpl::update_neighbour_stats(adnl::AdnlNodeIdShort adnl_id, do
|
|||
}
|
||||
}
|
||||
|
||||
void FullNodeShardImpl::got_neighbour_capabilities(adnl::AdnlNodeIdShort adnl_id, double t,
|
||||
td::BufferSlice data) {
|
||||
void FullNodeShardImpl::got_neighbour_capabilities(adnl::AdnlNodeIdShort adnl_id, double t, td::BufferSlice data) {
|
||||
auto it = neighbours_.find(adnl_id);
|
||||
if (it == neighbours_.end()) {
|
||||
return;
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
#pragma once
|
||||
|
||||
#include "full-node-shard.h"
|
||||
#include "td/actor/PromiseFuture.h"
|
||||
#include "td/utils/port/Poll.h"
|
||||
|
||||
namespace ton {
|
||||
|
||||
|
@ -139,6 +141,7 @@ class FullNodeShardImpl : public FullNodeShard {
|
|||
void process_broadcast(PublicKeyHash src, ton_api::tonNode_externalMessageBroadcast &query);
|
||||
void process_broadcast(PublicKeyHash src, ton_api::tonNode_newShardBlockBroadcast &query);
|
||||
void receive_broadcast(PublicKeyHash src, td::BufferSlice query);
|
||||
void check_broadcast(PublicKeyHash src, td::BufferSlice query, td::Promise<td::Unit> promise);
|
||||
|
||||
void send_ihr_message(td::BufferSlice data) override;
|
||||
void send_external_message(td::BufferSlice data) override;
|
||||
|
|
|
@ -124,6 +124,9 @@ class ValidatorManagerImpl : public ValidatorManager {
|
|||
//void get_block_description(BlockIdExt block_id, td::Promise<BlockDescription> promise) override;
|
||||
|
||||
void new_external_message(td::BufferSlice data) override;
|
||||
void check_external_message(td::BufferSlice data, td::Promise<td::Unit> promise) override {
|
||||
UNREACHABLE();
|
||||
}
|
||||
void new_ihr_message(td::BufferSlice data) override;
|
||||
void new_shard_block(BlockIdExt block_id, CatchainSeqno cc_seqno, td::BufferSlice data) override;
|
||||
|
||||
|
|
|
@ -144,6 +144,9 @@ class ValidatorManagerImpl : public ValidatorManager {
|
|||
void get_key_block_proof_link(BlockIdExt block_id, td::Promise<td::BufferSlice> promise) override;
|
||||
|
||||
void new_external_message(td::BufferSlice data) override;
|
||||
void check_external_message(td::BufferSlice data, td::Promise<td::Unit> promise) override {
|
||||
UNREACHABLE();
|
||||
}
|
||||
void new_ihr_message(td::BufferSlice data) override;
|
||||
void new_shard_block(BlockIdExt block_id, CatchainSeqno cc_seqno, td::BufferSlice data) override {
|
||||
UNREACHABLE();
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
|
||||
#include "interfaces/validator-manager.h"
|
||||
#include "interfaces/db.h"
|
||||
#include "td/actor/PromiseFuture.h"
|
||||
#include "td/utils/port/Poll.h"
|
||||
#include "validator-group.hpp"
|
||||
#include "shard-client.hpp"
|
||||
#include "manager-init.h"
|
||||
|
@ -325,6 +327,9 @@ class ValidatorManagerImpl : public ValidatorManager {
|
|||
//void get_block_description(BlockIdExt block_id, td::Promise<BlockDescription> promise) override;
|
||||
|
||||
void new_external_message(td::BufferSlice data) override;
|
||||
void check_external_message(td::BufferSlice data, td::Promise<td::Unit> promise) override {
|
||||
promise.set_value(td::Unit());
|
||||
}
|
||||
void new_ihr_message(td::BufferSlice data) override;
|
||||
void new_shard_block(BlockIdExt block_id, CatchainSeqno cc_seqno, td::BufferSlice data) override;
|
||||
|
||||
|
|
|
@ -94,9 +94,8 @@ struct ValidatorManagerOptions : public td::CntObject {
|
|||
BlockIdExt zero_block_id, BlockIdExt init_block_id,
|
||||
std::function<bool(ShardIdFull, CatchainSeqno, ShardCheckMode)> check_shard = [](ShardIdFull, CatchainSeqno,
|
||||
ShardCheckMode) { return true; },
|
||||
bool allow_blockchain_init = false, double sync_blocks_before = 300,
|
||||
double block_ttl = 86400 * 7, double state_ttl = 3600,
|
||||
double archive_ttl = 86400 * 365, double key_proof_ttl = 86400 * 3650,
|
||||
bool allow_blockchain_init = false, double sync_blocks_before = 300, double block_ttl = 86400 * 7,
|
||||
double state_ttl = 3600, double archive_ttl = 86400 * 365, double key_proof_ttl = 86400 * 3650,
|
||||
bool initial_sync_disabled = false);
|
||||
};
|
||||
|
||||
|
@ -176,6 +175,7 @@ class ValidatorManagerInterface : public td::actor::Actor {
|
|||
virtual void write_handle(BlockHandle handle, td::Promise<td::Unit> promise) = 0;
|
||||
|
||||
virtual void new_external_message(td::BufferSlice data) = 0;
|
||||
virtual void check_external_message(td::BufferSlice data, td::Promise<td::Unit> promise) = 0;
|
||||
virtual void new_ihr_message(td::BufferSlice data) = 0;
|
||||
virtual void new_shard_block(BlockIdExt block_id, CatchainSeqno cc_seqno, td::BufferSlice data) = 0;
|
||||
|
||||
|
|
Loading…
Reference in a new issue