mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
Allow untrusted fecs after check (#356)
* Allow untrusted fecs after check * FEC: save and resend incoming parts Co-authored-by: OmicronTau <87443739+OmicronTau@users.noreply.github.com> Co-authored-by: OmicronTau <omicron@ton.org>
This commit is contained in:
parent
0fbfc91965
commit
1e0b587023
4 changed files with 83 additions and 41 deletions
|
@ -59,14 +59,15 @@ td::Status OverlayFecBroadcastPart::check_source() {
|
||||||
return td::Status::Error(ErrorCode::error, "broadcast is forbidden");
|
return td::Status::Error(ErrorCode::error, "broadcast is forbidden");
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME
|
|
||||||
if (r == BroadcastCheckResult::NeedCheck) {
|
if (r == BroadcastCheckResult::NeedCheck) {
|
||||||
return td::Status::Error(ErrorCode::error, "broadcast is forbidden");
|
untrusted_ = true;
|
||||||
|
return td::Status::OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bcast_) {
|
if (bcast_) {
|
||||||
TRY_STATUS(bcast_->is_eligible_sender(source_));
|
TRY_STATUS(bcast_->is_eligible_sender(source_));
|
||||||
}
|
}
|
||||||
|
|
||||||
return td::Status::OK();
|
return td::Status::OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,6 +78,7 @@ td::Status OverlayFecBroadcastPart::check_signature() {
|
||||||
}
|
}
|
||||||
|
|
||||||
td::Status OverlayFecBroadcastPart::run_checks() {
|
td::Status OverlayFecBroadcastPart::run_checks() {
|
||||||
|
|
||||||
TRY_STATUS(check_time());
|
TRY_STATUS(check_time());
|
||||||
TRY_STATUS(check_duplicate());
|
TRY_STATUS(check_duplicate());
|
||||||
TRY_STATUS(check_source());
|
TRY_STATUS(check_source());
|
||||||
|
@ -84,7 +86,52 @@ td::Status OverlayFecBroadcastPart::run_checks() {
|
||||||
return td::Status::OK();
|
return td::Status::OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BroadcastFec::broadcast_checked(td::Result<td::Unit> R) {
|
||||||
|
if (R.is_error()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
overlay_->deliver_broadcast(get_source().compute_short_id(), data_.clone());
|
||||||
|
auto manager = overlay_->overlay_manager();
|
||||||
|
while (!parts_.empty()) {
|
||||||
|
distribute_part(parts_.begin()->first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do we need status here??
|
||||||
|
td::Status BroadcastFec::distribute_part(td::uint32 seqno) {
|
||||||
|
auto i = parts_.find(seqno);
|
||||||
|
if (i == parts_.end()) {
|
||||||
|
// should not get here
|
||||||
|
return td::Status::OK();
|
||||||
|
}
|
||||||
|
auto tls = std::move(i->second);
|
||||||
|
parts_.erase(i);
|
||||||
|
td::BufferSlice data_short = std::move(tls.first);
|
||||||
|
td::BufferSlice data = std::move(tls.second);
|
||||||
|
|
||||||
|
auto nodes = overlay_->get_neighbours(5);
|
||||||
|
auto manager = overlay_->overlay_manager();
|
||||||
|
|
||||||
|
for (auto &n : nodes) {
|
||||||
|
if (neighbour_completed(n)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (neighbour_received(n)) {
|
||||||
|
td::actor::send_closure(manager, &OverlayManager::send_message, n, overlay_->local_id(), overlay_->overlay_id(),
|
||||||
|
data_short.clone());
|
||||||
|
} else {
|
||||||
|
if (hash_.count_leading_zeroes() >= 12) {
|
||||||
|
VLOG(OVERLAY_INFO) << "broadcast " << hash_ << ": sending part " << seqno << " to " << n;
|
||||||
|
}
|
||||||
|
td::actor::send_closure(manager, &OverlayManager::send_message, n, overlay_->local_id(), overlay_->overlay_id(),
|
||||||
|
data.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return td::Status::OK();
|
||||||
|
}
|
||||||
|
|
||||||
td::Status OverlayFecBroadcastPart::apply() {
|
td::Status OverlayFecBroadcastPart::apply() {
|
||||||
|
|
||||||
if (!bcast_) {
|
if (!bcast_) {
|
||||||
bcast_ = overlay_->get_fec_broadcast(broadcast_hash_);
|
bcast_ = overlay_->get_fec_broadcast(broadcast_hash_);
|
||||||
}
|
}
|
||||||
|
@ -107,52 +154,31 @@ td::Status OverlayFecBroadcastPart::apply() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bcast_->finalized()) {
|
if (!bcast_->finalized()) {
|
||||||
TRY_STATUS(bcast_->add_part(seqno_, data_.clone()));
|
bcast_->set_overlay(overlay_);
|
||||||
|
TRY_STATUS(bcast_->add_part(seqno_, data_.clone(), export_serialized_short(), export_serialized()));
|
||||||
auto R = bcast_->finish();
|
auto R = bcast_->finish();
|
||||||
if (R.is_error()) {
|
if (R.is_error()) {
|
||||||
auto S = R.move_as_error();
|
auto S = R.move_as_error();
|
||||||
if (S.code() != ErrorCode::notready) {
|
if (S.code() != ErrorCode::notready) {
|
||||||
return S;
|
return S;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if(untrusted_) {
|
||||||
|
auto P = td::PromiseCreator::lambda(
|
||||||
|
[id = broadcast_hash_, overlay_id = actor_id(overlay_)](td::Result<td::Unit> RR) mutable {
|
||||||
|
td::actor::send_closure(std::move(overlay_id), &OverlayImpl::broadcast_checked, id, std::move(RR));
|
||||||
|
});
|
||||||
|
overlay_->check_broadcast(bcast_->get_source().compute_short_id(), R.move_as_ok(), std::move(P));
|
||||||
} else {
|
} else {
|
||||||
overlay_->deliver_broadcast(bcast_->get_source().compute_short_id(), R.move_as_ok());
|
overlay_->deliver_broadcast(bcast_->get_source().compute_short_id(), R.move_as_ok());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return td::Status::OK();
|
return td::Status::OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
td::Status OverlayFecBroadcastPart::distribute() {
|
td::Status OverlayFecBroadcastPart::distribute() {
|
||||||
auto B = export_serialized();
|
TRY_STATUS(bcast_->distribute_part(seqno_));
|
||||||
auto nodes = overlay_->get_neighbours(5);
|
|
||||||
|
|
||||||
auto manager = overlay_->overlay_manager();
|
|
||||||
|
|
||||||
td::BufferSlice data;
|
|
||||||
td::BufferSlice data_short;
|
|
||||||
|
|
||||||
for (auto &n : nodes) {
|
|
||||||
if (bcast_->neighbour_completed(n)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (bcast_->neighbour_received(n)) {
|
|
||||||
if (data_short.size() == 0) {
|
|
||||||
data_short = export_serialized_short();
|
|
||||||
}
|
|
||||||
td::actor::send_closure(manager, &OverlayManager::send_message, n, overlay_->local_id(), overlay_->overlay_id(),
|
|
||||||
data_short.clone());
|
|
||||||
} else {
|
|
||||||
if (data.size() == 0) {
|
|
||||||
data = export_serialized();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (broadcast_hash_.count_leading_zeroes() >= 12) {
|
|
||||||
VLOG(OVERLAY_INFO) << "broadcast " << broadcast_hash_ << ": sending part " << part_hash_ << " to " << n;
|
|
||||||
}
|
|
||||||
td::actor::send_closure(manager, &OverlayManager::send_message, n, overlay_->local_id(), overlay_->overlay_id(),
|
|
||||||
data.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return td::Status::OK();
|
return td::Status::OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,7 +214,6 @@ td::BufferSlice OverlayFecBroadcastPart::to_sign() {
|
||||||
td::Status OverlayFecBroadcastPart::create(OverlayImpl *overlay,
|
td::Status OverlayFecBroadcastPart::create(OverlayImpl *overlay,
|
||||||
tl_object_ptr<ton_api::overlay_broadcastFec> broadcast) {
|
tl_object_ptr<ton_api::overlay_broadcastFec> broadcast) {
|
||||||
TRY_STATUS(overlay->check_date(broadcast->date_));
|
TRY_STATUS(overlay->check_date(broadcast->date_));
|
||||||
|
|
||||||
auto source = PublicKey{broadcast->src_};
|
auto source = PublicKey{broadcast->src_};
|
||||||
auto part_data_hash = sha256_bits256(broadcast->data_.as_slice());
|
auto part_data_hash = sha256_bits256(broadcast->data_.as_slice());
|
||||||
|
|
||||||
|
|
|
@ -82,13 +82,17 @@ class BroadcastFec : public td::ListNode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
td::Status add_part(td::uint32 seqno, td::BufferSlice data) {
|
td::Status add_part(td::uint32 seqno, td::BufferSlice data,
|
||||||
|
td::BufferSlice serialized_fec_part_short,
|
||||||
|
td::BufferSlice serialized_fec_part) {
|
||||||
CHECK(decoder_);
|
CHECK(decoder_);
|
||||||
td::fec::Symbol s;
|
td::fec::Symbol s;
|
||||||
s.id = seqno;
|
s.id = seqno;
|
||||||
s.data = std::move(data);
|
s.data = std::move(data);
|
||||||
|
|
||||||
decoder_->add_symbol(std::move(s));
|
decoder_->add_symbol(std::move(s));
|
||||||
|
parts_[seqno] = std::pair<td::BufferSlice, td::BufferSlice>(std::move(serialized_fec_part_short),
|
||||||
|
std::move(serialized_fec_part));
|
||||||
|
|
||||||
return td::Status::OK();
|
return td::Status::OK();
|
||||||
}
|
}
|
||||||
|
@ -106,6 +110,7 @@ class BroadcastFec : public td::ListNode {
|
||||||
CHECK(encoder_ != nullptr);
|
CHECK(encoder_ != nullptr);
|
||||||
ready_ = true;
|
ready_ = true;
|
||||||
decoder_ = nullptr;
|
decoder_ = nullptr;
|
||||||
|
data_ = D.data.clone();
|
||||||
return std::move(D.data);
|
return std::move(D.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,9 +190,13 @@ class BroadcastFec : public td::ListNode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void broadcast_checked(td::Result<td::Unit> R) {
|
void broadcast_checked(td::Result<td::Unit> R);
|
||||||
|
void set_overlay(OverlayImpl *overlay) {
|
||||||
|
overlay_ = overlay;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
td::Status distribute_part(td::uint32 seqno);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool ready_ = false;
|
bool ready_ = false;
|
||||||
|
|
||||||
|
@ -208,6 +217,10 @@ class BroadcastFec : public td::ListNode {
|
||||||
|
|
||||||
td::uint32 next_seqno_ = 0;
|
td::uint32 next_seqno_ = 0;
|
||||||
td::uint64 received_parts_ = 0;
|
td::uint64 received_parts_ = 0;
|
||||||
|
|
||||||
|
std::map<td::uint32, std::pair<td::BufferSlice, td::BufferSlice>> parts_;
|
||||||
|
OverlayImpl *overlay_;
|
||||||
|
td::BufferSlice data_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class OverlayFecBroadcastPart : public td::ListNode {
|
class OverlayFecBroadcastPart : public td::ListNode {
|
||||||
|
@ -228,6 +241,7 @@ class OverlayFecBroadcastPart : public td::ListNode {
|
||||||
td::BufferSlice signature_;
|
td::BufferSlice signature_;
|
||||||
|
|
||||||
bool is_short_;
|
bool is_short_;
|
||||||
|
bool untrusted_{false};
|
||||||
|
|
||||||
BroadcastFec *bcast_;
|
BroadcastFec *bcast_;
|
||||||
OverlayImpl *overlay_;
|
OverlayImpl *overlay_;
|
||||||
|
@ -290,7 +304,9 @@ class OverlayFecBroadcastPart : public td::ListNode {
|
||||||
td::Status run() {
|
td::Status run() {
|
||||||
TRY_STATUS(run_checks());
|
TRY_STATUS(run_checks());
|
||||||
TRY_STATUS(apply());
|
TRY_STATUS(apply());
|
||||||
|
if(!untrusted_) {
|
||||||
TRY_STATUS(distribute());
|
TRY_STATUS(distribute());
|
||||||
|
}
|
||||||
return td::Status::OK();
|
return td::Status::OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -108,6 +108,7 @@ class OverlayPrivacyRules {
|
||||||
}
|
}
|
||||||
|
|
||||||
BroadcastCheckResult check_rules(PublicKeyHash hash, td::uint32 size, bool is_fec) {
|
BroadcastCheckResult check_rules(PublicKeyHash hash, td::uint32 size, bool is_fec) {
|
||||||
|
|
||||||
auto it = authorized_keys_.find(hash);
|
auto it = authorized_keys_.find(hash);
|
||||||
if (it == authorized_keys_.end()) {
|
if (it == authorized_keys_.end()) {
|
||||||
if (size > max_unath_size_) {
|
if (size > max_unath_size_) {
|
||||||
|
|
|
@ -896,7 +896,7 @@ void FullNodeShardImpl::update_validators(std::vector<PublicKeyHash> public_key_
|
||||||
authorized_keys.emplace(key, overlay::Overlays::max_fec_broadcast_size());
|
authorized_keys.emplace(key, overlay::Overlays::max_fec_broadcast_size());
|
||||||
}
|
}
|
||||||
|
|
||||||
rules_ = overlay::OverlayPrivacyRules{1 << 14, 0, std::move(authorized_keys)};
|
rules_ = overlay::OverlayPrivacyRules{overlay::Overlays::max_fec_broadcast_size(), overlay::CertificateFlags::AllowFec, std::move(authorized_keys)};
|
||||||
td::actor::send_closure(overlays_, &overlay::Overlays::set_privacy_rules, adnl_id_, overlay_id_, rules_);
|
td::actor::send_closure(overlays_, &overlay::Overlays::set_privacy_rules, adnl_id_, overlay_id_, rules_);
|
||||||
|
|
||||||
if (update_cert) {
|
if (update_cert) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue