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

added support for config change proposals

- added some fift scripts for the config change proposal voting
- added validator-engine-console support for the config change proposal voting
- additional sanity checks in catchain
- unsafe slow catchain resync method
This commit is contained in:
ton 2020-03-30 17:20:45 +04:00
parent a31f8d4424
commit 4dd5eea11f
35 changed files with 753 additions and 144 deletions

View file

@ -60,7 +60,8 @@ class CatChainReceiverInterface : public td::actor::Actor {
td::actor::ActorId<adnl::Adnl> adnl,
td::actor::ActorId<overlay::Overlays> overlay_manager,
std::vector<CatChainNode> ids, PublicKeyHash local_id,
CatChainSessionId unique_hash, std::string db_root);
CatChainSessionId unique_hash, std::string db_root,
bool allow_unsafe_self_blocks_resync);
virtual ~CatChainReceiverInterface() = default;
};

View file

@ -53,6 +53,9 @@ class CatChainReceiverSource {
virtual void block_received(CatChainBlockHeight height) = 0;
virtual void block_delivered(CatChainBlockHeight height) = 0;
virtual bool has_unreceived() const = 0;
virtual bool has_undelivered() const = 0;
virtual td::Status validate_dep_sync(tl_object_ptr<ton_api::catchain_block_dep> &dep) = 0;
virtual void on_new_block(CatChainReceivedBlock *block) = 0;
virtual void on_found_fork_proof(td::Slice fork) = 0;

View file

@ -78,6 +78,19 @@ class CatChainReceiverSourceImpl : public CatChainReceiverSource {
CatChainBlockHeight received_height() const override {
return received_height_;
}
bool has_unreceived() const override {
if (blamed()) {
return true;
}
if (!blocks_.size()) {
return false;
}
CHECK(blocks_.rbegin()->second->get_height() >= received_height_);
return blocks_.rbegin()->second->get_height() > received_height_;
}
bool has_undelivered() const override {
return delivered_height_ < received_height_;
}
CatChainReceivedBlock *get_block(CatChainBlockHeight height) const override;
td::Status validate_dep_sync(tl_object_ptr<ton_api::catchain_block_dep> &dep) override;

View file

@ -83,6 +83,16 @@ void CatChainReceiverImpl::receive_block(adnl::AdnlNodeIdShort src, tl_object_pt
return;
}
if (block->src_ == static_cast<td::int32>(local_idx_)) {
if (!allow_unsafe_self_blocks_resync_ || started_) {
LOG(FATAL) << this << ": received unknown SELF block from " << src
<< " (unsafe=" << allow_unsafe_self_blocks_resync_ << ")";
} else {
LOG(ERROR) << this << ": received unknown SELF block from " << src << ". UPDATING LOCAL DATABASE. UNSAFE";
initial_sync_complete_at_ = td::Timestamp::in(300.0);
}
}
auto raw_data = serialize_tl_object(block, true, payload.as_slice());
create_block(std::move(block), td::SharedSlice{payload.as_slice()});
@ -420,14 +430,16 @@ CatChainReceiverImpl::CatChainReceiverImpl(std::unique_ptr<Callback> callback, C
td::actor::ActorId<adnl::Adnl> adnl,
td::actor::ActorId<overlay::Overlays> overlay_manager,
std::vector<CatChainNode> ids, PublicKeyHash local_id,
CatChainSessionId unique_hash, std::string db_root)
CatChainSessionId unique_hash, std::string db_root,
bool allow_unsafe_self_blocks_resync)
: callback_(std::move(callback))
, opts_(std::move(opts))
, keyring_(keyring)
, adnl_(adnl)
, overlay_manager_(overlay_manager)
, local_id_(local_id)
, db_root_(db_root) {
, db_root_(db_root)
, allow_unsafe_self_blocks_resync_(allow_unsafe_self_blocks_resync) {
std::vector<td::Bits256> short_ids;
local_idx_ = static_cast<td::uint32>(ids.size());
for (auto &id : ids) {
@ -589,19 +601,20 @@ void CatChainReceiverImpl::read_db() {
next_rotate_ = td::Timestamp::in(60 + td::Random::fast(0, 60));
next_sync_ = td::Timestamp::in(0.001 * td::Random::fast(0, 60));
initial_sync_complete_at_ = td::Timestamp::in(allow_unsafe_self_blocks_resync_ ? 300.0 : 5.0);
alarm_timestamp().relax(next_rotate_);
alarm_timestamp().relax(next_sync_);
callback_->start();
alarm_timestamp().relax(initial_sync_complete_at_);
}
td::actor::ActorOwn<CatChainReceiverInterface> CatChainReceiverInterface::create(
std::unique_ptr<Callback> callback, CatChainOptions opts, td::actor::ActorId<keyring::Keyring> keyring,
td::actor::ActorId<adnl::Adnl> adnl, td::actor::ActorId<overlay::Overlays> overlay_manager,
std::vector<CatChainNode> ids, PublicKeyHash local_id, CatChainSessionId unique_hash, std::string db_root) {
std::vector<CatChainNode> ids, PublicKeyHash local_id, CatChainSessionId unique_hash, std::string db_root,
bool allow_unsafe_self_blocks_resync) {
auto A = td::actor::create_actor<CatChainReceiverImpl>("catchainreceiver", std::move(callback), std::move(opts),
keyring, adnl, overlay_manager, std::move(ids), local_id,
unique_hash, db_root);
unique_hash, db_root, allow_unsafe_self_blocks_resync);
return std::move(A);
}
@ -906,6 +919,59 @@ void CatChainReceiverImpl::choose_neighbours() {
neighbours_ = std::move(n);
}
bool CatChainReceiverImpl::unsafe_start_up_check_completed() {
auto S = get_source(local_idx_);
CHECK(!S->blamed());
if (S->has_unreceived() || S->has_undelivered()) {
LOG(INFO) << "catchain: has_unreceived=" << S->has_unreceived() << " has_undelivered=" << S->has_undelivered();
run_scheduler();
initial_sync_complete_at_ = td::Timestamp::in(60.0);
return false;
}
auto h = S->delivered_height();
if (h == 0) {
CHECK(last_sent_block_->get_height() == 0);
CHECK(!unsafe_root_block_writing_);
return true;
}
if (last_sent_block_->get_height() == h) {
CHECK(!unsafe_root_block_writing_);
return true;
}
if (unsafe_root_block_writing_) {
initial_sync_complete_at_ = td::Timestamp::in(5.0);
LOG(INFO) << "catchain: writing=true";
return false;
}
unsafe_root_block_writing_ = true;
auto B = S->get_block(h);
CHECK(B != nullptr);
CHECK(B->delivered());
CHECK(B->in_db());
auto id = B->get_hash();
td::BufferSlice raw_data{32};
raw_data.as_slice().copy_from(as_slice(id));
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this), block = B](td::Result<td::Unit> R) mutable {
R.ensure();
td::actor::send_closure(SelfId, &CatChainReceiverImpl::written_unsafe_root_block, block);
});
db_.set(CatChainBlockHash::zero(), std::move(raw_data), std::move(P), 0);
initial_sync_complete_at_ = td::Timestamp::in(5.0);
LOG(INFO) << "catchain: need update root";
return false;
}
void CatChainReceiverImpl::written_unsafe_root_block(CatChainReceivedBlock *block) {
CHECK(last_sent_block_->get_height() < block->get_height());
last_sent_block_ = block;
unsafe_root_block_writing_ = false;
}
void CatChainReceiverImpl::alarm() {
alarm_timestamp() = td::Timestamp::never();
if (next_sync_ && next_sync_.is_in_past()) {
@ -923,8 +989,22 @@ void CatChainReceiverImpl::alarm() {
next_rotate_ = td::Timestamp::in(td::Random::fast(60.0, 120.0));
choose_neighbours();
}
if (!started_ && read_db_ && initial_sync_complete_at_ && initial_sync_complete_at_.is_in_past()) {
bool allow = false;
if (allow_unsafe_self_blocks_resync_) {
allow = unsafe_start_up_check_completed();
} else {
allow = true;
}
if (allow) {
initial_sync_complete_at_ = td::Timestamp::never();
started_ = true;
callback_->start();
}
}
alarm_timestamp().relax(next_rotate_);
alarm_timestamp().relax(next_sync_);
alarm_timestamp().relax(initial_sync_complete_at_);
}
void CatChainReceiverImpl::send_fec_broadcast(td::BufferSlice data) {

View file

@ -134,6 +134,9 @@ class CatChainReceiverImpl : public CatChainReceiver {
void block_written_to_db(CatChainBlockHash hash);
bool unsafe_start_up_check_completed();
void written_unsafe_root_block(CatChainReceivedBlock *block);
void destroy() override;
CatChainReceivedBlock *get_block(CatChainBlockHash hash) const;
@ -141,7 +144,7 @@ class CatChainReceiverImpl : public CatChainReceiver {
CatChainReceiverImpl(std::unique_ptr<Callback> callback, CatChainOptions opts,
td::actor::ActorId<keyring::Keyring> keyring, td::actor::ActorId<adnl::Adnl> adnl,
td::actor::ActorId<overlay::Overlays>, std::vector<CatChainNode> ids, PublicKeyHash local_id,
CatChainBlockHash unique_hash, std::string db_root);
CatChainBlockHash unique_hash, std::string db_root, bool allow_unsafe_self_blocks_resync);
private:
std::unique_ptr<overlay::Overlays::Callback> make_callback() {
@ -222,6 +225,10 @@ class CatChainReceiverImpl : public CatChainReceiver {
DbType db_;
bool intentional_fork_ = false;
td::Timestamp initial_sync_complete_at_{td::Timestamp::never()};
bool allow_unsafe_self_blocks_resync_{false};
bool unsafe_root_block_writing_{false};
bool started_{false};
std::list<CatChainReceivedBlock *> to_run_;
};

View file

@ -222,8 +222,9 @@ void CatChainImpl::on_receiver_started() {
CatChainImpl::CatChainImpl(std::unique_ptr<Callback> callback, CatChainOptions opts,
td::actor::ActorId<keyring::Keyring> keyring, td::actor::ActorId<adnl::Adnl> adnl,
td::actor::ActorId<overlay::Overlays> overlay_manager, std::vector<CatChainNode> ids,
PublicKeyHash local_id, CatChainSessionId unique_hash, std::string db_root)
: opts_(std::move(opts)), db_root_(db_root) {
PublicKeyHash local_id, CatChainSessionId unique_hash, std::string db_root,
bool allow_unsafe_self_blocks_resync)
: opts_(std::move(opts)), db_root_(db_root), allow_unsafe_self_blocks_resync_(allow_unsafe_self_blocks_resync) {
callback_ = std::move(callback);
sources_.resize(ids.size());
unique_hash_ = unique_hash;
@ -280,9 +281,9 @@ void CatChainImpl::start_up() {
auto cb = std::make_unique<ChainCb>(actor_id(this));
receiver_ =
CatChainReceiverInterface::create(std::move(cb), opts_, args_->keyring, args_->adnl, args_->overlay_manager,
std::move(args_->ids), args_->local_id, args_->unique_hash, db_root_);
receiver_ = CatChainReceiverInterface::create(std::move(cb), opts_, args_->keyring, args_->adnl,
args_->overlay_manager, std::move(args_->ids), args_->local_id,
args_->unique_hash, db_root_, allow_unsafe_self_blocks_resync_);
args_ = nullptr;
//alarm_timestamp() = td::Timestamp::in(opts_.idle_timeout);
}
@ -292,9 +293,11 @@ td::actor::ActorOwn<CatChain> CatChain::create(std::unique_ptr<Callback> callbac
td::actor::ActorId<adnl::Adnl> adnl,
td::actor::ActorId<overlay::Overlays> overlay_manager,
std::vector<CatChainNode> ids, PublicKeyHash local_id,
CatChainSessionId unique_hash, std::string db_root) {
CatChainSessionId unique_hash, std::string db_root,
bool allow_unsafe_self_blocks_resync) {
return td::actor::create_actor<CatChainImpl>("catchain", std::move(callback), std::move(opts), keyring, adnl,
overlay_manager, std::move(ids), local_id, unique_hash, db_root);
overlay_manager, std::move(ids), local_id, unique_hash, db_root,
allow_unsafe_self_blocks_resync);
}
CatChainBlock *CatChainImpl::get_block(CatChainBlockHash hash) const {

View file

@ -102,7 +102,8 @@ class CatChain : public td::actor::Actor {
td::actor::ActorId<adnl::Adnl> adnl,
td::actor::ActorId<overlay::Overlays> overlay_manager,
std::vector<CatChainNode> ids, PublicKeyHash local_id,
CatChainSessionId unique_hash, std::string db_root);
CatChainSessionId unique_hash, std::string db_root,
bool allow_unsafe_self_blocks_resync);
virtual ~CatChain() = default;
};

View file

@ -51,6 +51,7 @@ class CatChainImpl : public CatChain {
bool receiver_started_ = false;
std::string db_root_;
bool allow_unsafe_self_blocks_resync_;
void send_process();
void send_preprocess(CatChainBlock *block);
@ -118,7 +119,7 @@ class CatChainImpl : public CatChain {
CatChainImpl(std::unique_ptr<Callback> callback, CatChainOptions opts, td::actor::ActorId<keyring::Keyring> keyring,
td::actor::ActorId<adnl::Adnl> adnl, td::actor::ActorId<overlay::Overlays> overlay_manager,
std::vector<CatChainNode> ids, PublicKeyHash local_id, CatChainSessionId unique_hash,
std::string db_root);
std::string db_root, bool allow_unsafe_self_blocks_resync);
void alarm() override;
void start_up() override;