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

updated func/fift

- updated func/fift
- updated liteclient/liteserver
- bugfixes
This commit is contained in:
ton 2019-12-29 12:14:12 +03:00
parent d41ce55305
commit acf16718e6
45 changed files with 1360 additions and 185 deletions

View file

@ -143,19 +143,80 @@ Ref<Cell> MerkleProof::virtualize(Ref<Cell> cell, int virtualization) {
return virtualize_raw(r_raw.move_as_ok(), {0 /*level*/, static_cast<td::uint8>(virtualization)});
}
class MerkleProofCombineFast {
public:
MerkleProofCombineFast(Ref<Cell> a, Ref<Cell> b) : a_(std::move(a)), b_(std::move(b)) {
}
td::Result<Ref<Cell>> run() {
TRY_RESULT_ASSIGN(a_, unpack_proof(a_));
TRY_RESULT_ASSIGN(b_, unpack_proof(b_));
TRY_RESULT(res, run_raw());
return CellBuilder::create_merkle_proof(std::move(res));
}
td::Result<Ref<Cell>> run_raw() {
if (a_->get_hash(0) != b_->get_hash(0)) {
return td::Status::Error("Can't combine MerkleProofs with different roots");
}
return merge(a_, b_, 0);
}
private:
Ref<Cell> a_;
Ref<Cell> b_;
Ref<Cell> merge(Ref<Cell> a, Ref<Cell> b, td::uint32 merkle_depth) {
if (a->get_hash() == b->get_hash()) {
return a;
}
if (a->get_level() == merkle_depth) {
return a;
}
if (b->get_level() == merkle_depth) {
return b;
}
CellSlice csa(NoVm(), a);
CellSlice csb(NoVm(), b);
if (csa.is_special() && csa.special_type() == vm::Cell::SpecialType::PrunnedBranch) {
return b;
}
if (csb.is_special() && csb.special_type() == vm::Cell::SpecialType::PrunnedBranch) {
return a;
}
CHECK(csa.size_refs() != 0);
auto child_merkle_depth = csa.child_merkle_depth(merkle_depth);
CellBuilder cb;
cb.store_bits(csa.fetch_bits(csa.size()));
for (unsigned i = 0; i < csa.size_refs(); i++) {
cb.store_ref(merge(csa.prefetch_ref(i), csb.prefetch_ref(i), child_merkle_depth));
}
return cb.finalize(csa.is_special());
}
};
class MerkleProofCombine {
public:
MerkleProofCombine(Ref<Cell> a, Ref<Cell> b) : a_(std::move(a)), b_(std::move(b)) {
}
td::Result<Ref<Cell>> run() {
TRY_RESULT(a, unpack_proof(a_));
TRY_RESULT(b, unpack_proof(b_));
if (a->get_hash(0) != b->get_hash(0)) {
TRY_RESULT_ASSIGN(a_, unpack_proof(a_));
TRY_RESULT_ASSIGN(b_, unpack_proof(b_));
TRY_RESULT(res, run_raw());
return CellBuilder::create_merkle_proof(std::move(res));
}
td::Result<Ref<Cell>> run_raw() {
if (a_->get_hash(0) != b_->get_hash(0)) {
return td::Status::Error("Can't combine MerkleProofs with different roots");
}
dfs(a, 0);
dfs(b, 0);
return CellBuilder::create_merkle_proof(create_A(a, 0, 0));
dfs(a_, 0);
dfs(b_, 0);
return create_A(a_, 0, 0);
}
private:
@ -262,6 +323,30 @@ Ref<Cell> MerkleProof::combine(Ref<Cell> a, Ref<Cell> b) {
return res.move_as_ok();
}
Ref<Cell> MerkleProof::combine_fast(Ref<Cell> a, Ref<Cell> b) {
auto res = MerkleProofCombineFast(std::move(a), std::move(b)).run();
if (res.is_error()) {
return {};
}
return res.move_as_ok();
}
Ref<Cell> MerkleProof::combine_raw(Ref<Cell> a, Ref<Cell> b) {
auto res = MerkleProofCombine(std::move(a), std::move(b)).run_raw();
if (res.is_error()) {
return {};
}
return res.move_as_ok();
}
Ref<Cell> MerkleProof::combine_fast_raw(Ref<Cell> a, Ref<Cell> b) {
auto res = MerkleProofCombineFast(std::move(a), std::move(b)).run_raw();
if (res.is_error()) {
return {};
}
return res.move_as_ok();
}
MerkleProofBuilder::MerkleProofBuilder(Ref<Cell> root)
: usage_tree(std::make_shared<CellUsageTree>()), orig_root(std::move(root)) {
usage_root = UsageCell::create(orig_root, usage_tree->root_ptr());

View file

@ -38,12 +38,15 @@ class MerkleProof {
static Ref<Cell> virtualize(Ref<Cell> cell, int virtualization);
static Ref<Cell> combine(Ref<Cell> a, Ref<Cell> b);
static Ref<Cell> combine_fast(Ref<Cell> a, Ref<Cell> b);
// works with upwrapped proofs
// works fine with cell of non-zero level, but this is not supported (yet?) in MerkeProof special cell
static Ref<Cell> generate_raw(Ref<Cell> cell, IsPrunnedFunction is_prunned);
static Ref<Cell> generate_raw(Ref<Cell> cell, CellUsageTree *usage_tree);
static Ref<Cell> virtualize_raw(Ref<Cell> cell, Cell::VirtualizationParameters virt);
static Ref<Cell> combine_raw(Ref<Cell> a, Ref<Cell> b);
static Ref<Cell> combine_fast_raw(Ref<Cell> a, Ref<Cell> b);
};
class MerkleProofBuilder {

View file

@ -268,7 +268,7 @@ class MerkleCombine {
// 1. Create maximum subtrees of X and Z with all cells in A, B, C and D
// Max(V) - such maximum subtree
//
// 2. Max(A) and Max(D) should be merkle update already. But win want to minimize it
// 2. Max(A) and Max(D) should be merkle update already. But we want to minimize it
// So we cut all branches of Max(D) which are in maxA
// When we cut branch q in Max(D) we mark some path to q in Max(A)
// Then we cut all branches of Max(A) which are not marked.