Skip to content

Remove concept of virtualization level #1648

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: testnet
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
set(CMAKE_CXX_EXTENSIONS FALSE)

set(CMAKE_COLOR_DIAGNOSTICS TRUE)

#BEGIN internal
option(BUILD_SHARED_LIBS "Use \"ON\" to build shared libraries instead of static where it's not specified (not recommended)" OFF)
option(USE_EMSCRIPTEN "Use \"ON\" for config building wasm." OFF)
Expand Down
4 changes: 2 additions & 2 deletions blockchain-explorer/blockchain-explorer-http.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ HttpAnswer& HttpAnswer::operator<<(AccountCell acc_c) {
last_trans_hash.set_zero();
block::CurrencyCollection balance = block::CurrencyCollection::zero();
try {
auto state_root = vm::MerkleProof::virtualize(acc_c.q_roots[1], 1);
auto state_root = vm::MerkleProof::virtualize(acc_c.q_roots[1]);
if (state_root.is_null()) {
abort("account state proof is invalid");
return *this;
Expand Down Expand Up @@ -474,7 +474,7 @@ HttpAnswer& HttpAnswer::operator<<(BlockHeaderCell head_c) {
vm::CellSlice cs{vm::NoVm(), head_c.root};
auto block_id = head_c.block_id;
try {
auto virt_root = vm::MerkleProof::virtualize(head_c.root, 1);
auto virt_root = vm::MerkleProof::virtualize(head_c.root);
if (virt_root.is_null()) {
abort("invalid merkle proof");
return *this;
Expand Down
1 change: 0 additions & 1 deletion crypto/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ set(TON_CRYPTO_CORE_SOURCE
vm/cells/PrunnedCell.h
vm/cells/UsageCell.h
vm/cells/VirtualCell.h
vm/cells/VirtualizationParameters.h

vm/cells.h
vm/cellslice.h
Expand Down
22 changes: 11 additions & 11 deletions crypto/block/check-proof.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ td::Status check_block_header_proof(td::Ref<vm::Cell> root, ton::BlockIdExt blki

td::Result<td::Bits256> check_state_proof(ton::BlockIdExt blkid, td::Slice proof) {
TRY_RESULT(proof_root, vm::std_boc_deserialize(proof));
auto virt_root = vm::MerkleProof::virtualize(std::move(proof_root), 1);
auto virt_root = vm::MerkleProof::virtualize(std::move(proof_root));
if (virt_root.is_null()) {
return td::Status::Error("account state proof is invalid");
}
Expand All @@ -86,7 +86,7 @@ td::Result<Ref<vm::Cell>> check_extract_state_proof(ton::BlockIdExt blkid, td::S
try {
TRY_RESULT(state_hash, check_state_proof(blkid, proof));
TRY_RESULT(state_root, vm::std_boc_deserialize(data));
auto state_virt_root = vm::MerkleProof::virtualize(std::move(state_root), 1);
auto state_virt_root = vm::MerkleProof::virtualize(std::move(state_root));
if (state_virt_root.is_null()) {
return td::Status::Error("account state proof is invalid");
}
Expand Down Expand Up @@ -118,13 +118,13 @@ td::Status check_shard_proof(ton::BlockIdExt blk, ton::BlockIdExt shard_blk, td:
return td::Status::Error("shard configuration proof must have exactly two roots");
}
try {
auto mc_state_root = vm::MerkleProof::virtualize(std::move(P_roots[1]), 1);
auto mc_state_root = vm::MerkleProof::virtualize(std::move(P_roots[1]));
if (mc_state_root.is_null()) {
return td::Status::Error("shard configuration proof is invalid");
}
ton::Bits256 mc_state_hash = mc_state_root->get_hash().bits();
TRY_STATUS_PREFIX(
check_block_header_proof(vm::MerkleProof::virtualize(std::move(P_roots[0]), 1), blk, &mc_state_hash, true),
check_block_header_proof(vm::MerkleProof::virtualize(std::move(P_roots[0])), blk, &mc_state_hash, true),
"error in shard configuration block header proof :");
block::gen::ShardStateUnsplit::Record sstate;
if (!(tlb::unpack_cell(mc_state_root, sstate))) {
Expand Down Expand Up @@ -171,12 +171,12 @@ td::Status check_account_proof(td::Slice proof, ton::BlockIdExt shard_blk, const
}

try {
auto state_root = vm::MerkleProof::virtualize(std::move(Q_roots[1]), 1);
auto state_root = vm::MerkleProof::virtualize(std::move(Q_roots[1]));
if (state_root.is_null()) {
return td::Status::Error("account state proof is invalid");
}
ton::Bits256 state_hash = state_root->get_hash().bits();
TRY_STATUS_PREFIX(check_block_header_proof(vm::MerkleProof::virtualize(std::move(Q_roots[0]), 1), shard_blk,
TRY_STATUS_PREFIX(check_block_header_proof(vm::MerkleProof::virtualize(std::move(Q_roots[0])), shard_blk,
&state_hash, true, save_utime, save_lt),
"error in account shard block header proof : ");
block::gen::ShardStateUnsplit::Record sstate;
Expand Down Expand Up @@ -223,7 +223,7 @@ td::Result<AccountState::Info> AccountState::validate(ton::BlockIdExt ref_blk, b
Ref<vm::Cell> root;

if (is_virtualized && true_root.not_null()) {
root = vm::MerkleProof::virtualize(true_root, 1);
root = vm::MerkleProof::virtualize(true_root);
if (root.is_null()) {
return td::Status::Error("account state proof is invalid");
}
Expand Down Expand Up @@ -346,7 +346,7 @@ td::Result<BlockTransactionList::Info> BlockTransactionList::validate(bool check
if (check_proof) {
try {
TRY_RESULT(proof_cell, vm::std_boc_deserialize(std::move(proof_boc)));
auto virt_root = vm::MerkleProof::virtualize(proof_cell, 1);
auto virt_root = vm::MerkleProof::virtualize(proof_cell);

if (blkid.root_hash != virt_root->get_hash().bits()) {
return td::Status::Error("Invalid block proof root hash");
Expand Down Expand Up @@ -452,15 +452,15 @@ td::Status BlockProofLink::validate(td::uint32* save_utime) const {
}
try {
// virtualize Merkle proof roots
auto vs_root = vm::MerkleProof::virtualize(proof, 1);
auto vs_root = vm::MerkleProof::virtualize(proof);
if (vs_root.is_null()) {
return td::Status::Error("BlockProofLink contains an invalid Merkle proof for source block "s + from.to_str());
}
ton::Bits256 state_hash;
if (from.seqno()) {
TRY_STATUS(check_block_header(vs_root, from, is_fwd ? nullptr : &state_hash));
}
auto vd_root = dest_proof.not_null() ? vm::MerkleProof::virtualize(dest_proof, 1) : Ref<vm::Cell>{};
auto vd_root = dest_proof.not_null() ? vm::MerkleProof::virtualize(dest_proof) : Ref<vm::Cell>{};
if (vd_root.is_null() && to.seqno()) {
return td::Status::Error("BlockProofLink contains an invalid Merkle proof for destination block "s + to.to_str());
}
Expand All @@ -483,7 +483,7 @@ td::Status BlockProofLink::validate(td::uint32* save_utime) const {
}
if (!is_fwd) {
// check a backward link
auto vstate_root = vm::MerkleProof::virtualize(state_proof, 1);
auto vstate_root = vm::MerkleProof::virtualize(state_proof);
if (vstate_root.is_null()) {
return td::Status::Error("backward BlockProofLink contains an invalid Merkle proof for source state "s +
from.to_str());
Expand Down
42 changes: 21 additions & 21 deletions crypto/test/test-db.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -663,13 +663,13 @@ TEST(Cell, MerkleProof) {
auto proof = MerkleProof::generate(cell, is_prunned);
// CellBuilder::virtualize(proof, 1);
//ASSERT_EQ(1u, proof->get_level());
auto virtualized_proof = MerkleProof::virtualize(proof, 1);
auto virtualized_proof = MerkleProof::virtualize(proof);
auto exploration3 = CellExplorer::explore(virtualized_proof, exploration.ops);
ASSERT_EQ(exploration.log, exploration3.log);

auto proof2 = MerkleProof::generate(cell, usage_tree.get());
CHECK(proof2->get_depth() == proof->get_depth());
auto virtualized_proof2 = MerkleProof::virtualize(proof2, 1);
auto virtualized_proof2 = MerkleProof::virtualize(proof2);
auto exploration4 = CellExplorer::explore(virtualized_proof2, exploration.ops);
ASSERT_EQ(exploration.log, exploration4.log);
}
Expand All @@ -690,7 +690,7 @@ TEST(Cell, MerkleProofCombine) {
CellExplorer::explore(usage_cell, exploration1.ops);
proof1 = MerkleProof::generate(cell, usage_tree.get());

auto virtualized_proof = MerkleProof::virtualize(proof1, 1);
auto virtualized_proof = MerkleProof::virtualize(proof1);
auto exploration = CellExplorer::explore(virtualized_proof, exploration1.ops);
ASSERT_EQ(exploration.log, exploration1.log);
}
Expand All @@ -702,7 +702,7 @@ TEST(Cell, MerkleProofCombine) {
CellExplorer::explore(usage_cell, exploration2.ops);
proof2 = MerkleProof::generate(cell, usage_tree.get());

auto virtualized_proof = MerkleProof::virtualize(proof2, 1);
auto virtualized_proof = MerkleProof::virtualize(proof2);
auto exploration = CellExplorer::explore(virtualized_proof, exploration2.ops);
ASSERT_EQ(exploration.log, exploration2.log);
}
Expand All @@ -715,7 +715,7 @@ TEST(Cell, MerkleProofCombine) {
CellExplorer::explore(usage_cell, exploration2.ops);
proof12 = MerkleProof::generate(cell, usage_tree.get());

auto virtualized_proof = MerkleProof::virtualize(proof12, 1);
auto virtualized_proof = MerkleProof::virtualize(proof12);
auto exploration_a = CellExplorer::explore(virtualized_proof, exploration1.ops);
auto exploration_b = CellExplorer::explore(virtualized_proof, exploration2.ops);
ASSERT_EQ(exploration_a.log, exploration1.log);
Expand All @@ -724,7 +724,7 @@ TEST(Cell, MerkleProofCombine) {

{
auto check = [&](auto proof_union) {
auto virtualized_proof = MerkleProof::virtualize(proof_union, 1);
auto virtualized_proof = MerkleProof::virtualize(proof_union);
auto exploration_a = CellExplorer::explore(virtualized_proof, exploration1.ops);
auto exploration_b = CellExplorer::explore(virtualized_proof, exploration2.ops);
ASSERT_EQ(exploration_a.log, exploration1.log);
Expand All @@ -738,14 +738,14 @@ TEST(Cell, MerkleProofCombine) {
check(proof_union_fast);
}
{
cell = MerkleProof::virtualize(proof12, 1);
cell = MerkleProof::virtualize(proof12);

auto usage_tree = std::make_shared<CellUsageTree>();
auto usage_cell = UsageCell::create(cell, usage_tree->root_ptr());
CellExplorer::explore(usage_cell, exploration1.ops);
auto proof = MerkleProof::generate(cell, usage_tree.get());

auto virtualized_proof = MerkleProof::virtualize(proof, 2);
auto virtualized_proof = MerkleProof::virtualize(proof);
auto exploration = CellExplorer::explore(virtualized_proof, exploration1.ops);
ASSERT_EQ(exploration.log, exploration1.log);
if (proof->get_hash() != proof1->get_hash()) {
Expand Down Expand Up @@ -2152,28 +2152,28 @@ TEST(Cell, MerkleProofHands) {
test_boc_deserializer_full(merkle_proof).ensure();

{
auto virtual_node = proof->virtualize({0, 1});
auto virtual_node = proof->virtualize(0);
ASSERT_EQ(0u, virtual_node->get_level());
ASSERT_EQ(1u, virtual_node->get_virtualization());
ASSERT_EQ(1u, virtual_node->is_virtualized());
CellSlice cs{NoVm(), virtual_node};
auto virtual_data = cs.fetch_ref();
ASSERT_EQ(0u, virtual_data->get_level());
ASSERT_EQ(1u, virtual_data->get_virtualization());
ASSERT_EQ(1u, virtual_data->is_virtualized());
ASSERT_EQ(data->get_hash(), virtual_data->get_hash());

auto virtual_node_copy =
CellBuilder{}.store_bits(node->get_data(), node->get_bits()).store_ref(virtual_data).finalize();
ASSERT_EQ(0u, virtual_node_copy->get_level());
ASSERT_EQ(1u, virtual_node_copy->get_virtualization());
ASSERT_EQ(1u, virtual_node_copy->is_virtualized());
ASSERT_EQ(virtual_node->get_hash(), virtual_node_copy->get_hash());

{
auto two_nodes = CellBuilder{}.store_ref(virtual_node).store_ref(node).finalize();
ASSERT_EQ(0u, two_nodes->get_level());
ASSERT_EQ(1u, two_nodes->get_virtualization());
ASSERT_EQ(1u, two_nodes->is_virtualized());
CellSlice cs2(NoVm(), two_nodes);
ASSERT_EQ(1u, cs2.prefetch_ref(0)->get_virtualization());
ASSERT_EQ(0u, cs2.prefetch_ref(1)->get_virtualization());
ASSERT_EQ(1u, cs2.prefetch_ref(0)->is_virtualized());
ASSERT_EQ(0u, cs2.prefetch_ref(1)->is_virtualized());
}
}
LOG(ERROR) << td::NamedThreadSafeCounter::get_default();
Expand All @@ -2195,7 +2195,7 @@ TEST(Cell, MerkleProofArrayHands) {
ASSERT_TRUE(proof->get_hash(1) != arr.root()->get_hash(1));
ASSERT_EQ(arr.root()->get_hash(0), arr.root()->get_hash(1));

CompactArray new_arr(arr.size(), proof->virtualize({0, 1}));
CompactArray new_arr(arr.size(), proof->virtualize(0));
for (auto k : keys) {
ASSERT_EQ(arr.get(k), new_arr.get(k));
}
Expand All @@ -2222,7 +2222,7 @@ TEST(Cell, MerkleProofCombineArray) {
}
}

CompactArray arr2(n, vm::MerkleProof::virtualize(root, 1));
CompactArray arr2(n, vm::MerkleProof::virtualize(root));
for (size_t i = 0; i < n; i++) {
CHECK(arr.get(i) == arr2.get(i));
}
Expand Down Expand Up @@ -2920,7 +2920,7 @@ TEST(TonDb, BocRespectsUsageCell) {
auto usage_cell = vm::UsageCell::create(cell, usage_tree->root_ptr());
auto serialization = serialize_boc(usage_cell);
auto proof = vm::MerkleProof::generate(cell, usage_tree.get());
auto virtualized_proof = vm::MerkleProof::virtualize(proof, 1);
auto virtualized_proof = vm::MerkleProof::virtualize(proof);
auto serialization_of_virtualized_cell = serialize_boc(virtualized_proof);
ASSERT_STREQ(serialization, serialization_of_virtualized_cell);
}
Expand All @@ -2946,7 +2946,7 @@ TEST(UsageTree, ThreadSafe) {
thread.join();
}
auto proof = vm::MerkleProof::generate(cell, usage_tree.get());
auto virtualized_proof = vm::MerkleProof::virtualize(proof, 1);
auto virtualized_proof = vm::MerkleProof::virtualize(proof);
for (auto &exploration : explorations) {
auto new_exploration = vm::CellExplorer::explore(virtualized_proof, exploration.ops);
ASSERT_EQ(exploration.log, new_exploration.log);
Expand Down Expand Up @@ -3024,8 +3024,8 @@ TEST(TonDb, DoNotMakeListsPrunned) {
auto cell = vm::CellBuilder().store_bytes("abc").finalize();
auto is_prunned = [&](const td::Ref<vm::Cell> &cell) { return true; };
auto proof = vm::MerkleProof::generate(cell, is_prunned);
auto virtualized_proof = vm::MerkleProof::virtualize(proof, 1);
ASSERT_TRUE(virtualized_proof->get_virtualization() == 0);
auto virtualized_proof = vm::MerkleProof::virtualize(proof);
ASSERT_TRUE(!virtualized_proof->is_virtualized());
}

TEST(TonDb, CellStat) {
Expand Down
4 changes: 2 additions & 2 deletions crypto/vm/boc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ int BagOfCells::add_root(td::Ref<vm::Cell> add_root) {
if (add_root.is_null()) {
return 0;
}
LOG_CHECK(add_root->get_virtualization() == 0) << "TODO: support serialization of virtualized cells";
LOG_CHECK(!add_root->is_virtualized()) << "TODO: support serialization of virtualized cells";
//const Cell::Hash& hash = add_root->get_hash();
//for (const auto& root_info : roots) {
//if (root_info.cell->get_hash() == hash) {
Expand Down Expand Up @@ -217,7 +217,7 @@ td::Result<int> BagOfCells::import_cell(td::Ref<vm::Cell> cell, int depth) {
cell_list_[pos].should_cache = true;
return pos;
}
if (cell->get_virtualization() != 0) {
if (cell->is_virtualized()) {
return td::Status::Error(
"error while importing a cell into a bag of cells: cell has non-zero virtualization level");
}
Expand Down
4 changes: 2 additions & 2 deletions crypto/vm/cells/Cell.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ td::Status Cell::check_equals_unloaded(const Ref<Cell>& other) const {
return td::Status::OK();
}

Ref<Cell> Cell::virtualize(VirtualizationParameters virt) const {
return VirtualCell::create(virt, Ref<Cell>(this));
Ref<Cell> Cell::virtualize(td::uint32 effective_level) const {
return VirtualCell::create(effective_level, Ref<Cell>(this));
}

std::ostream& operator<<(std::ostream& os, const Cell& c) {
Expand Down
9 changes: 4 additions & 5 deletions crypto/vm/cells/Cell.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
#include "vm/cells/CellTraits.h"
#include "vm/cells/CellUsageTree.h"
#include "vm/cells/LevelMask.h"
#include "vm/cells/VirtualizationParameters.h"

#include "td/utils/Status.h"

Expand All @@ -38,10 +37,9 @@ class DataCell;
class Cell : public CellTraits {
public:
using LevelMask = detail::LevelMask;
using VirtualizationParameters = detail::VirtualizationParameters;
struct LoadedCell {
Ref<DataCell> data_cell;
VirtualizationParameters virt;
td::uint32 effective_level;
CellUsageTree::NodePtr tree_node; // TODO: inline_vector?
};

Expand All @@ -57,8 +55,9 @@ class Cell : public CellTraits {
// load interface
virtual td::Status set_data_cell(Ref<DataCell> &&data_cell) const = 0;
virtual td::Result<LoadedCell> load_cell() const = 0;
virtual Ref<Cell> virtualize(VirtualizationParameters virt) const;
virtual td::uint32 get_virtualization() const = 0;
virtual Ref<Cell> virtualize(td::uint32 effective_level) const;
// Cell is virtualized if its effective level is less than its actual level.
virtual bool is_virtualized() const = 0;
virtual CellUsageTree::NodePtr get_tree_node() const = 0;
virtual bool is_loaded() const = 0;

Expand Down
2 changes: 1 addition & 1 deletion crypto/vm/cells/CellBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ Ref<DataCell> CellBuilder::finalize(bool special) {
}

Ref<Cell> CellBuilder::create_pruned_branch(Ref<Cell> cell, td::uint32 new_level, td::uint32 virt_level) {
if (cell->is_loaded() && cell->get_level() <= virt_level && cell->get_virtualization() == 0) {
if (cell->is_loaded() && cell->get_level() <= virt_level && !cell->is_virtualized()) {
CellSlice cs(NoVm{}, cell);
if (cs.size_refs() == 0) {
return cell;
Expand Down
Loading