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

updated tonlib, fixed bugs

updated tonlib
fixed bugs in func
validator: partial support for hardforks
liteserver: support for waitMasterchainBlock prefix
transactions: support for gas flat rate
This commit is contained in:
ton 2019-10-03 17:04:52 +04:00
parent 841d5ebac2
commit 7ea00ebfcf
89 changed files with 1922 additions and 608 deletions

View file

@ -229,6 +229,73 @@ tl_object_ptr<ton_api::db_blockdb_lru> BlockDb::DbEntry::release() {
return create_tl_object<ton_api::db_blockdb_lru>(create_tl_block_id(block_id), prev, next);
}
void BlockDb::truncate(td::Ref<MasterchainState> state, td::Promise<td::Unit> promise) {
std::map<ShardIdFull, BlockSeqno> max_seqno;
max_seqno.emplace(ShardIdFull{masterchainId}, state->get_seqno() + 1);
auto shards = state->get_shards();
auto it = KeyHash::zero();
kv_->begin_transaction().ensure();
while (true) {
auto R = get_block_lru(it);
R.ensure();
auto v = R.move_as_ok();
it = v.next;
R = get_block_lru(it);
R.ensure();
v = R.move_as_ok();
if (v.is_empty()) {
break;
}
auto s = v.block_id.shard_full();
if (!max_seqno.count(s)) {
bool found = false;
for (auto &shard : shards) {
if (shard_intersects(shard->shard(), s)) {
found = true;
max_seqno.emplace(s, shard->top_block_id().seqno() + 1);
break;
}
}
if (!found) {
max_seqno.emplace(s, 0);
}
}
bool to_delete = v.block_id.seqno() >= max_seqno[s];
if (to_delete) {
auto key_hash = get_block_value_key(v.block_id);
auto B = get_block_value(key_hash);
B.ensure();
auto handleR = create_block_handle(B.move_as_ok());
handleR.ensure();
auto handle = handleR.move_as_ok();
handle->unsafe_clear_applied();
handle->unsafe_clear_next();
if (handle->need_flush()) {
set_block_value(key_hash, handle->serialize());
}
} else if (v.block_id.seqno() + 1 == max_seqno[s]) {
auto key_hash = get_block_value_key(v.block_id);
auto B = get_block_value(key_hash);
B.ensure();
auto handleR = create_block_handle(B.move_as_ok());
handleR.ensure();
auto handle = handleR.move_as_ok();
handle->unsafe_clear_next();
if (handle->need_flush()) {
set_block_value(key_hash, handle->serialize());
}
}
}
kv_->commit_transaction().ensure();
}
} // namespace validator
} // namespace ton

View file

@ -41,6 +41,8 @@ class BlockDb : public td::actor::Actor {
void gc();
void skip_gc();
void truncate(td::Ref<MasterchainState> state, td::Promise<td::Unit> promise);
BlockDb(td::actor::ActorId<RootDb> root_db, std::string db_path);
private:

View file

@ -138,7 +138,7 @@ void FileDb::load_file(RefId ref_id, td::Promise<td::BufferSlice> promise) {
}
});
td::actor::create_actor<db::ReadFile>("readfile", get_file_name(ref_id, false), 0, -1, std::move(P)).release();
td::actor::create_actor<db::ReadFile>("readfile", get_file_name(ref_id, false), 0, -1, 0, std::move(P)).release();
}
void FileDb::load_file_slice(RefId ref_id, td::int64 offset, td::int64 max_size, td::Promise<td::BufferSlice> promise) {
@ -159,7 +159,7 @@ void FileDb::load_file_slice(RefId ref_id, td::int64 offset, td::int64 max_size,
}
});
td::actor::create_actor<db::ReadFile>("readfile", get_file_name(ref_id, false), offset, max_size, std::move(P))
td::actor::create_actor<db::ReadFile>("readfile", get_file_name(ref_id, false), offset, max_size, 0, std::move(P))
.release();
}

View file

@ -81,25 +81,32 @@ class WriteFile : public td::actor::Actor {
class ReadFile : public td::actor::Actor {
public:
enum Flags : td::uint32 { f_disable_log = 1 };
void start_up() override {
auto S = td::read_file(file_name_, max_length_, offset_);
if (S.is_ok()) {
promise_.set_result(S.move_as_ok());
} else {
// TODO check error code
LOG(ERROR) << "missing file " << file_name_;
if (flags_ & Flags::f_disable_log) {
LOG(DEBUG) << "missing file " << file_name_;
} else {
LOG(ERROR) << "missing file " << file_name_;
}
promise_.set_error(td::Status::Error(ErrorCode::notready, "file does not exist"));
}
stop();
}
ReadFile(std::string file_name, td::int64 offset, td::int64 max_length, td::Promise<td::BufferSlice> promise)
: file_name_(file_name), offset_(offset), max_length_(max_length), promise_(std::move(promise)) {
ReadFile(std::string file_name, td::int64 offset, td::int64 max_length, td::uint32 flags,
td::Promise<td::BufferSlice> promise)
: file_name_(file_name), offset_(offset), max_length_(max_length), flags_(flags), promise_(std::move(promise)) {
}
private:
std::string file_name_;
td::int64 offset_;
td::int64 max_length_;
td::uint32 flags_;
td::Promise<td::BufferSlice> promise_;
};

View file

@ -216,6 +216,95 @@ void LtDb::start_up() {
kv_ = std::make_shared<td::RocksDb>(td::RocksDb::open(db_path_).move_as_ok());
}
void LtDb::truncate_workchain(ShardIdFull shard, td::Ref<MasterchainState> state) {
auto key = get_desc_key(shard);
std::string value;
auto R = kv_->get(key, value);
R.ensure();
CHECK(R.move_as_ok() == td::KeyValue::GetStatus::Ok);
auto F = fetch_tl_object<ton_api::db_lt_desc_value>(td::BufferSlice{value}, true);
F.ensure();
auto f = F.move_as_ok();
auto shards = state->get_shards();
BlockSeqno seqno = 0;
if (shard.is_masterchain()) {
seqno = state->get_seqno();
} else {
for (auto s : shards) {
if (shard_intersects(s->shard(), shard)) {
seqno = s->top_block_id().seqno();
break;
}
}
}
while (f->last_idx_ > f->first_idx_) {
auto db_key = get_el_key(shard, f->last_idx_ - 1);
R = kv_->get(db_key, value);
R.ensure();
CHECK(R.move_as_ok() == td::KeyValue::GetStatus::Ok);
auto E = fetch_tl_object<ton_api::db_lt_el_value>(td::BufferSlice{value}, true);
E.ensure();
auto e = E.move_as_ok();
bool to_delete = static_cast<td::uint32>(e->id_->seqno_) > seqno;
if (!to_delete) {
break;
} else {
f->last_idx_--;
kv_->erase(db_key).ensure();
}
}
if (f->first_idx_ == f->last_idx_) {
f->last_ts_ = 0;
f->last_lt_ = 0;
f->last_seqno_ = 0;
}
kv_->set(key, serialize_tl_object(f, true)).ensure();
}
void LtDb::truncate(td::Ref<MasterchainState> state, td::Promise<td::Unit> promise) {
auto status_key = create_serialize_tl_object<ton_api::db_lt_status_key>();
td::Result<td::KeyValue::GetStatus> R;
td::uint32 total_shards = 0;
{
std::string value;
R = kv_->get(status_key.as_slice(), value);
R.ensure();
if (R.move_as_ok() == td::KeyValue::GetStatus::NotFound) {
promise.set_value(td::Unit());
return;
}
auto F = fetch_tl_object<ton_api::db_lt_status_value>(value, true);
F.ensure();
auto f = F.move_as_ok();
total_shards = f->total_shards_;
if (total_shards == 0) {
promise.set_value(td::Unit());
return;
}
}
kv_->begin_transaction().ensure();
for (td::uint32 idx = 0; idx < total_shards; idx++) {
auto shard_key = create_serialize_tl_object<ton_api::db_lt_shard_key>(idx);
std::string value;
R = kv_->get(shard_key.as_slice(), value);
R.ensure();
CHECK(R.move_as_ok() == td::KeyValue::GetStatus::Ok);
auto F = fetch_tl_object<ton_api::db_lt_shard_value>(value, true);
F.ensure();
auto f = F.move_as_ok();
truncate_workchain(ShardIdFull{f->workchain_, static_cast<td::uint64>(f->shard_)}, state);
}
kv_->commit_transaction().ensure();
promise.set_value(td::Unit());
}
} // namespace validator
} // namespace ton

View file

@ -20,6 +20,7 @@
#include "td/actor/actor.h"
#include "td/db/KeyValueAsync.h"
#include "validator/interfaces/db.h"
#include "ton/ton-types.h"
@ -42,6 +43,9 @@ class LtDb : public td::actor::Actor {
void get_block_by_unix_time(AccountIdPrefixFull account_id, UnixTime ts, td::Promise<BlockIdExt> promise);
void get_block_by_seqno(AccountIdPrefixFull account_id, BlockSeqno seqno, td::Promise<BlockIdExt> promise);
void truncate_workchain(ShardIdFull shard, td::Ref<MasterchainState> state);
void truncate(td::Ref<MasterchainState> state, td::Promise<td::Unit> promise);
void start_up() override;
LtDb(td::actor::ActorId<RootDb> root_db, std::string db_path) : root_db_(root_db), db_path_(std::move(db_path)) {

View file

@ -25,6 +25,7 @@
#include "td/utils/overloaded.h"
#include "common/checksum.h"
#include "validator/stats-merger.h"
#include "td/actor/MultiPromise.h"
namespace ton {
@ -413,6 +414,14 @@ void RootDb::get_async_serializer_state(td::Promise<AsyncSerializerState> promis
td::actor::send_closure(state_db_, &StateDb::get_async_serializer_state, std::move(promise));
}
void RootDb::update_hardforks(std::vector<BlockIdExt> blocks, td::Promise<td::Unit> promise) {
td::actor::send_closure(state_db_, &StateDb::update_hardforks, std::move(blocks), std::move(promise));
}
void RootDb::get_hardforks(td::Promise<std::vector<BlockIdExt>> promise) {
td::actor::send_closure(state_db_, &StateDb::get_hardforks, std::move(promise));
}
void RootDb::start_up() {
cell_db_ = td::actor::create_actor<CellDb>("celldb", actor_id(this), root_path_ + "/celldb/");
block_db_ = td::actor::create_actor<BlockDb>("blockdb", actor_id(this), root_path_ + "/blockdb/");
@ -481,6 +490,15 @@ void RootDb::prepare_stats(td::Promise<std::vector<std::pair<std::string, std::s
td::actor::send_closure(archive_db_, &FileDb::prepare_stats, merger.make_promise("archivedb."));
}
void RootDb::truncate(td::Ref<MasterchainState> state, td::Promise<td::Unit> promise) {
td::MultiPromise mp;
auto ig = mp.init_guard();
ig.add_promise(std::move(promise));
td::actor::send_closure(lt_db_, &LtDb::truncate, state, ig.get_promise());
td::actor::send_closure(block_db_, &BlockDb::truncate, state, ig.get_promise());
}
} // namespace validator
} // namespace ton

View file

@ -104,6 +104,9 @@ class RootDb : public Db {
void update_async_serializer_state(AsyncSerializerState state, td::Promise<td::Unit> promise) override;
void get_async_serializer_state(td::Promise<AsyncSerializerState> promise) override;
void update_hardforks(std::vector<BlockIdExt> blocks, td::Promise<td::Unit> promise) override;
void get_hardforks(td::Promise<std::vector<BlockIdExt>> promise) override;
void archive(BlockIdExt block_id, td::Promise<td::Unit> promise) override;
void allow_state_gc(BlockIdExt block_id, td::Promise<bool> promise);
@ -112,6 +115,8 @@ class RootDb : public Db {
void prepare_stats(td::Promise<std::vector<std::pair<std::string, std::string>>> promise) override;
void truncate(td::Ref<MasterchainState> state, td::Promise<td::Unit> promise) override;
private:
td::actor::ActorId<ValidatorManager> validator_manager_;

View file

@ -179,6 +179,44 @@ void StateDb::get_async_serializer_state(td::Promise<AsyncSerializerState> promi
static_cast<UnixTime>(obj->last_ts_)});
}
void StateDb::update_hardforks(std::vector<BlockIdExt> blocks, td::Promise<td::Unit> promise) {
auto key = create_hash_tl_object<ton_api::db_state_key_hardforks>();
std::vector<tl_object_ptr<ton_api::tonNode_blockIdExt>> vec;
for (auto &e : blocks) {
vec.push_back(create_tl_block_id(e));
}
kv_->begin_transaction().ensure();
kv_->set(key.as_slice(), create_serialize_tl_object<ton_api::db_state_hardforks>(std::move(vec))).ensure();
kv_->commit_transaction();
promise.set_value(td::Unit());
}
void StateDb::get_hardforks(td::Promise<std::vector<BlockIdExt>> promise) {
auto key = create_hash_tl_object<ton_api::db_state_key_hardforks>();
std::string value;
auto R = kv_->get(key.as_slice(), value);
R.ensure();
if (R.move_as_ok() == td::KeyValue::GetStatus::NotFound) {
promise.set_value(std::vector<BlockIdExt>{});
return;
}
auto F = fetch_tl_object<ton_api::db_state_hardforks>(value, true);
F.ensure();
auto f = F.move_as_ok();
std::vector<BlockIdExt> vec;
for (auto &e : f->blocks_) {
vec.push_back(create_block_id(e));
}
promise.set_value(std::move(vec));
}
StateDb::StateDb(td::actor::ActorId<RootDb> root_db, std::string db_path) : root_db_(root_db), db_path_(db_path) {
}

View file

@ -47,6 +47,9 @@ class StateDb : public td::actor::Actor {
void update_async_serializer_state(AsyncSerializerState state, td::Promise<td::Unit> promise);
void get_async_serializer_state(td::Promise<AsyncSerializerState> promise);
void update_hardforks(std::vector<BlockIdExt> blocks, td::Promise<td::Unit> promise);
void get_hardforks(td::Promise<std::vector<BlockIdExt>> promise);
StateDb(td::actor::ActorId<RootDb> root_db, std::string path);
void start_up() override;

View file

@ -25,7 +25,9 @@ namespace validator {
void StaticFilesDb::load_file(FileHash file_hash, td::Promise<td::BufferSlice> promise) {
auto path = path_ + "/" + file_hash.to_hex();
td::actor::create_actor<db::ReadFile>("read file", path, 0, -1, std::move(promise)).release();
td::actor::create_actor<db::ReadFile>("read file", path, 0, -1, db::ReadFile::Flags::f_disable_log,
std::move(promise))
.release();
}
} // namespace validator