@@ -83,6 +83,11 @@ inline td::Result<unsigned> read_uint(td::BitSlice& bs, int bits) {
8383
8484// Decode DepthBalanceInfo and extract grams using TLB methods
8585td::RefInt256 extract_balance_from_depth_balance_info (vm::CellSlice& cs) {
86+ // Check hashmap label is empty ('00')
87+ if (cs.size () < 2 || cs.fetch_ulong (2 ) != 0 ) {
88+ return td::RefInt256{};
89+ }
90+
8691 int split_depth;
8792 Ref<vm::CellSlice> balance_cs_ref;
8893 if (!block::gen::t_DepthBalanceInfo.unpack_depth_balance (cs, split_depth, balance_cs_ref)) {
@@ -96,71 +101,24 @@ td::RefInt256 extract_balance_from_depth_balance_info(vm::CellSlice& cs) {
96101 }
97102 auto balance_cs = balance_cs_ref.write ();
98103 auto res = block::tlb::t_Grams.as_integer_skip (balance_cs);
99- if (balance_cs.size () != 1 ) {
100- return td::RefInt256{};
101- }
102- int last_bit = balance_cs.fetch_ulong (1 );
103- if (last_bit != 0 ) {
104+ if (balance_cs.size () != 1 || balance_cs.fetch_ulong (1 ) != 0 ) {
104105 return td::RefInt256{};
105106 }
106107 return res;
107108}
108109
109- // Skip Hashmap label for ShardAccounts (expecting '00' for empty label at root)
110- bool skip_hashmap_label (vm::CellSlice& cs, int /* max_bits*/ ) {
111- int k = cs.fetch_ulong (2 );
112- if (k != 0 ) {
113- return false ;
114- }
115- return true ;
116- }
117-
118110// Process ShardAccounts vertex and compute balance difference (right - left)
119111td::RefInt256 process_shard_accounts_vertex (vm::CellSlice& cs_left, vm::CellSlice& cs_right) {
120- if (skip_hashmap_label (cs_left, 256 ) && skip_hashmap_label (cs_right, 256 )) {
121- auto balance_left = extract_balance_from_depth_balance_info (cs_left);
122- auto balance_right = extract_balance_from_depth_balance_info (cs_right);
123- if (balance_left.not_null () && balance_right.not_null ()) {
124- td::RefInt256 diff = balance_right;
125- diff -= balance_left;
126- return diff;
127- }
112+ auto balance_left = extract_balance_from_depth_balance_info (cs_left);
113+ auto balance_right = extract_balance_from_depth_balance_info (cs_right);
114+ if (balance_left.not_null () && balance_right.not_null ()) {
115+ td::RefInt256 diff = balance_right;
116+ diff -= balance_left;
117+ return diff;
128118 }
129119 return td::RefInt256{};
130120}
131121
132- // Rebuild the ShardAccounts vertex from left + children diffs and compare with right
133- bool reconstruct_shard_vertex_and_compare (vm::CellSlice cs_left, vm::CellSlice cs_right, const td::RefInt256& sum_child_diff) {
134- if (!skip_hashmap_label (cs_left, 256 )) {
135- return false ;
136- }
137- auto left_grams = extract_balance_from_depth_balance_info (cs_left);
138- if (left_grams.is_null ()) {
139- return false ;
140- }
141- td::RefInt256 expected_right_grams = left_grams;
142- expected_right_grams += sum_child_diff;
143-
144- vm::CellBuilder cb;
145- if (!cb.store_zeroes_bool (2 )) {
146- return false ;
147- }
148- if (!cb.store_zeroes_bool (5 )) {
149- return false ;
150- }
151- if (!block::tlb::t_CurrencyCollection.pack_special (cb, expected_right_grams, td::Ref<vm::Cell>())) {
152- return false ;
153- }
154- td::Ref<vm::Cell> built_cell;
155- try {
156- built_cell = cb.finalize (false );
157- } catch (vm::CellBuilder::CellWriteError&) {
158- return false ;
159- }
160- vm::CellSlice built_cs (NoVm (), built_cell);
161- return built_cs.as_bitslice ().to_hex () == cs_right.as_bitslice ().to_hex ();
162- }
163-
164122td::Result<td::BufferSlice> boc_compress_improved_structure_lz4 (const std::vector<td::Ref<vm::Cell>>& boc_roots) {
165123 const bool kMURemoveSubtreeSums = true ;
166124 // Input validation
@@ -234,18 +192,11 @@ td::Result<td::BufferSlice> boc_compress_improved_structure_lz4(const std::vecto
234192 TRY_RESULT (child_left_id, self (self, cell_slice.prefetch_ref (0 )));
235193 boc_graph[current_cell_id][0 ] = child_left_id;
236194 // Right branch: traverse paired with left and compute diffs inline
237- td::RefInt256 right_sum_diff = td::make_refint (0 );
238195 TRY_RESULT (child_right_id, self (self,
239196 cell_slice.prefetch_ref (1 ),
240197 cell_slice.prefetch_ref (0 ),
241- true ,
242- &right_sum_diff));
198+ true ));
243199 boc_graph[current_cell_id][1 ] = child_right_id;
244- // Any extra refs if present
245- for (int i = 2 ; i < cell_slice.size_refs (); ++i) {
246- TRY_RESULT (child_id, self (self, cell_slice.prefetch_ref (i)));
247- boc_graph[current_cell_id][i] = child_id;
248- }
249200 } else if (under_mu_right && left_cell.not_null ()) {
250201 // Inline computation for RIGHT subtree nodes under MerkleUpdate
251202 vm::CellSlice cs_left (NoVm (), left_cell);
@@ -764,9 +715,6 @@ td::Result<std::vector<td::Ref<vm::Cell>>> boc_decompress_improved_structure_lz4
764715 if (is_depth_balance[right_idx] && left_idx != std::numeric_limits<size_t >::max ()) {
765716 // Extract left grams
766717 vm::CellSlice cs_left (NoVm (), nodes[left_idx]);
767- if (!skip_hashmap_label (cs_left, 256 )) {
768- return td::Status::Error (" BOC decompression failed: failed to skip hashmap label" );
769- }
770718 td::RefInt256 left_grams = extract_balance_from_depth_balance_info (cs_left);
771719 if (left_grams.is_null ()) {
772720 return td::Status::Error (" BOC decompression failed: depth-balance left vertex has no grams" );
0 commit comments