1
0
Fork 0
mirror of https://github.com/ton-blockchain/ton synced 2025-02-13 11:42:18 +00:00
ton/crypto/vm/db/TonDb.h
birydrad 72020c04c4
celldb in-memory mode, stats for actors, perf counters, minor fix in rldp2 (#1164)
* getactorstats query for validator-engine-console

* celldb in-memory mode (--celldb-in-memory option)

* rldp2: bugfix - do not estimate speed while nothing is sent

* add simple ed25519 benchmark

* fix compilation errors of different platforms and move to c++20

* fix some warnings

* turn on TON_USE_ABSEIL for glibc 2.27 nix build

---------

Co-authored-by: birydrad <>
2024-09-23 17:34:37 +03:00

194 lines
5.3 KiB
C++

/*
This file is part of TON Blockchain Library.
TON Blockchain Library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
TON Blockchain Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2020 Telegram Systems LLP
*/
#pragma once
#include "vm/cellslice.h"
#include "vm/cells.h"
#include "vm/boc.h"
#include "td/db/KeyValue.h"
#include "vm/db/CellStorage.h"
#include "vm/db/CellHashTable.h"
#include "td/utils/Slice.h"
#include "td/utils/Status.h"
namespace vm {
class SmartContractDbImpl;
using SmartContractDb = std::unique_ptr<SmartContractDbImpl>;
using KeyValue = td::KeyValue;
using KeyValueReader = td::KeyValueReader;
struct SmartContractMeta {
DynamicBagOfCellsDb::Stats stats;
enum BagOfCellsType { Dynamic, Static } type{Static};
template <class StorerT>
void store(StorerT &storer) const;
template <class ParserT>
void parse(ParserT &parser);
};
class SmartContractDbImpl {
public:
Ref<Cell> get_root();
SmartContractMeta get_meta();
td::Status validate_meta();
void set_root(Ref<Cell> new_root);
SmartContractDbImpl(td::Slice hash, std::shared_ptr<KeyValueReader> kv);
private:
std::string hash_;
std::shared_ptr<KeyValueReader> kv_;
bool sync_root_with_db_{false};
Ref<Cell> db_root_;
Ref<Cell> new_root_;
SmartContractMeta meta_;
bool is_dynamic_commit_;
std::string boc_to_commit_;
std::unique_ptr<DynamicBagOfCellsDb> cell_db_;
std::unique_ptr<BagOfCells> bag_of_cells_;
friend class SmartContractDiff;
friend class TonDbTransactionImpl;
void sync_root_with_db();
td::Slice hash() const {
return hash_;
}
void prepare_transaction();
void commit_transaction(KeyValue &kv);
void set_reader(std::shared_ptr<KeyValueReader> reader);
bool is_dynamic() const;
void prepare_commit_dynamic(bool force);
void prepare_commit_static(bool force);
bool is_root_changed() const;
};
class SmartContractDiff {
public:
explicit SmartContractDiff(SmartContractDb db) : db_(std::move(db)) {
db_->prepare_transaction();
}
SmartContractDb extract_smartcontract() {
return std::move(db_);
}
td::Slice hash() const {
return db_->hash();
}
void commit_transaction(KeyValue &kv) {
db_->commit_transaction(kv);
}
private:
SmartContractDb db_;
};
class TonDbTransactionImpl;
using TonDbTransaction = std::unique_ptr<TonDbTransactionImpl>;
class TonDbTransactionImpl {
public:
SmartContractDb begin_smartcontract(td::Slice hash = std::string(32, '\0'));
void commit_smartcontract(SmartContractDb txn);
void commit_smartcontract(SmartContractDiff txn);
void abort_smartcontract(SmartContractDb txn);
void abort_smartcontract(SmartContractDiff txn);
TonDbTransactionImpl(std::shared_ptr<KeyValue> kv);
private:
std::shared_ptr<KeyValue> kv_;
std::shared_ptr<KeyValueReader> reader_;
td::uint64 generation_{0};
struct SmartContractInfo {
bool is_inited{false};
td::uint64 generation_{0};
std::string hash;
SmartContractDb smart_contract_db;
bool operator<(const SmartContractInfo &other) const {
return hash < other.hash;
}
friend bool operator<(const SmartContractInfo &info, td::Slice hash) {
return info.hash < hash;
}
friend bool operator<(td::Slice hash, const SmartContractInfo &info) {
return hash < info.hash;
}
struct Eq {
using is_transparent = void; // Pred to use
bool operator()(const SmartContractInfo &info, const SmartContractInfo &other_info) const { return info.hash == other_info.hash;}
bool operator()(const SmartContractInfo &info, td::Slice hash) const { return info.hash == hash;}
bool operator()(td::Slice hash, const SmartContractInfo &info) const { return info.hash == hash;}
};
struct Hash {
using is_transparent = void; // Pred to use
using transparent_key_equal = Eq;
size_t operator()(td::Slice hash) const { return cell_hash_slice_hash(hash); }
size_t operator()(const SmartContractInfo &info) const { return cell_hash_slice_hash(info.hash);}
};
};
CellHashTable<SmartContractInfo> contracts_;
KeyValue &kv() {
return *kv_;
}
friend class TonDbImpl;
void begin();
void commit();
void abort();
void clear_cache();
void end_smartcontract(SmartContractDb smart_contract);
};
class TonDbImpl;
using TonDb = std::unique_ptr<TonDbImpl>;
class TonDbImpl {
public:
TonDbImpl(std::unique_ptr<KeyValue> kv);
~TonDbImpl();
TonDbTransaction begin_transaction();
void commit_transaction(TonDbTransaction transaction);
void abort_transaction(TonDbTransaction transaction);
void clear_cache();
static td::Result<TonDb> open(td::Slice path);
std::string stats() const;
private:
std::shared_ptr<KeyValue> kv_;
TonDbTransaction transaction_;
};
} // namespace vm