@@ -62,39 +62,64 @@ int keccak256_slice(slice s) inline {
62
62
{-
63
63
This function reads a specified number of bits from the input slice and stores them in a cell structure,
64
64
handling data that may exceed the maximum cell capacity in FunC (1023 bits).
65
+ Optimized to build cells directly in forward order without double reversal.
65
66
66
67
Parameters:
67
68
- in_msg_body: The input slice containing the data to be read
68
69
- size: The number of bits to read from the input
69
70
Returns:
70
71
- A tuple containing:
71
72
1. A cell containing the read data, potentially spanning multiple cells if the size exceeds 1016 bits
72
- 2. A slice containing the remaining unread data from the input
73
+ 2. A slice containing the remaining unread data from the input
73
74
74
75
Note:
75
76
- The function uses a maximum of 1016 bits per cell (instead of 1023) to ensure byte alignment
76
77
- If the input data exceeds 1016 bits, it is split into multiple cells linked by references
78
+ - Uses direct forward construction to avoid gas-inefficient double reversal
77
79
-}
78
80
(cell, slice) read_and_store_large_data(slice in_msg_body, int size) {
79
- (cell chunks, slice remaining) = split_into_reverse_chunks(in_msg_body, size);
80
- cell last_cell = null();
81
- while (~ cell_null?(chunks)) {
82
- slice chunk = chunks.begin_parse();
83
- builder cb = begin_cell().store_slice(chunk~load_bits(chunk.slice_bits()));
84
- if (~ cell_null?(last_cell)) {
85
- cb = cb.store_ref(last_cell);
81
+ ;; Collect chunks in order as we build them
82
+ tuple chunk_list = empty_tuple();
83
+ int total_bits_loaded = 0;
84
+ builder current_builder = begin_cell();
85
+
86
+ while ((~ in_msg_body.slice_empty?()) & (total_bits_loaded < size)) {
87
+ int bits_to_load = min(min(in_msg_body.slice_bits(), MAX_BITS - current_builder.builder_bits()), size - total_bits_loaded);
88
+ current_builder = current_builder.store_slice(in_msg_body~load_bits(bits_to_load));
89
+ total_bits_loaded += bits_to_load;
90
+
91
+ if ((current_builder.builder_bits() == MAX_BITS) | (size - total_bits_loaded == 0)) {
92
+ cell current_chunk = current_builder.end_cell();
93
+ chunk_list~tpush(current_chunk);
94
+ current_builder = begin_cell();
86
95
}
87
- last_cell = cb.end_cell();
88
- if (chunk.slice_refs_empty?()) {
89
- chunks = null();
90
- } else {
91
- chunks = chunk~load_ref();
96
+
97
+ if ((in_msg_body.slice_bits() == 0) & (~ in_msg_body.slice_refs_empty?())) {
98
+ in_msg_body = in_msg_body~load_ref().begin_parse();
92
99
}
93
100
}
94
-
95
- return (last_cell, remaining);
101
+
102
+ ;; Build forward chain: first chunk → second chunk → third chunk etc
103
+ cell result = null();
104
+ int chunk_count = chunk_list.tlen();
105
+
106
+ if (chunk_count > 0) {
107
+ ;; Start from the last chunk (no references)
108
+ result = chunk_list.at(chunk_count - 1);
109
+
110
+ ;; Build forward by adding references from earlier chunks to later chunks
111
+ int i = chunk_count - 2;
112
+ while (i >= 0) {
113
+ cell current_chunk = chunk_list.at(i);
114
+ result = begin_cell().store_slice(current_chunk.begin_parse()).store_ref(result).end_cell();
115
+ i -= 1;
116
+ }
117
+ }
118
+
119
+ return (result, in_msg_body);
96
120
}
97
121
122
+
98
123
(int) pubkey_to_eth_address(int x1, int x2) {
99
124
slice pubkey = begin_cell()
100
125
.store_uint(x1, 256)
0 commit comments