@layerzerolabs/layerzero-v2-ton 3.0.22-ton.2 → 3.0.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/build/AllStorages.compiled.json +1 -1
- package/build/AllStorages.test.compiled.json +1 -1
- package/build/BaseContract.test.compiled.json +1 -1
- package/build/Channel.compiled.json +1 -1
- package/build/Channel.permissions.test.compiled.json +1 -1
- package/build/ChannelBurn.test.compiled.json +1 -1
- package/build/ChannelCommitPacket.test.compiled.json +1 -1
- package/build/ChannelConfig.test.compiled.json +1 -1
- package/build/ChannelInitialize.test.compiled.json +1 -1
- package/build/ChannelMsglibIntegration.test.compiled.json +1 -1
- package/build/ChannelMsglibSendCallback.test.compiled.json +1 -1
- package/build/ChannelNilify.test.compiled.json +1 -1
- package/build/ChannelReceive.test.compiled.json +1 -1
- package/build/ChannelReceiveCallback.test.compiled.json +1 -1
- package/build/ChannelReceiveView.test.compiled.json +1 -1
- package/build/ChannelSend.test.compiled.json +1 -1
- package/build/Classlib.test.compiled.json +1 -1
- package/build/ComputeDataSizeGas.test.compiled.json +1 -1
- package/build/Connection.compiled.json +1 -1
- package/build/Controller.assertions.test.compiled.json +1 -1
- package/build/Controller.compiled.json +1 -1
- package/build/Controller.permissions.test.compiled.json +1 -1
- package/build/Controller.test.compiled.json +1 -1
- package/build/Counter.compiled.json +1 -1
- package/build/Counter.permissions.test.compiled.json +1 -1
- package/build/Counter.setters.test.compiled.json +1 -1
- package/build/Counter.test.compiled.json +1 -1
- package/build/Dvn.compiled.json +1 -1
- package/build/Dvn.test.compiled.json +1 -1
- package/build/DvnFeeLib.compiled.json +1 -1
- package/build/DvnPermissions.test.compiled.json +1 -1
- package/build/Endpoint.compiled.json +1 -1
- package/build/Endpoint.permissions.test.compiled.json +1 -1
- package/build/Endpoint.test.compiled.json +1 -1
- package/build/EndpointSetEpConfigDefaults.test.compiled.json +1 -1
- package/build/Executor.compiled.json +1 -1
- package/build/Executor.test.compiled.json +1 -1
- package/build/ExecutorFeeLib.compiled.json +1 -1
- package/build/ExecutorPermissions.test.compiled.json +1 -1
- package/build/LzClasses.test.compiled.json +1 -1
- package/build/LzUtil.test.compiled.json +1 -1
- package/build/MsgData.test.compiled.json +1 -1
- package/build/MsglibPacketCodec.test.compiled.json +1 -1
- package/build/PipelinedOutOfOrder.test.compiled.json +1 -1
- package/build/PriceFeedCache.compiled.json +1 -1
- package/build/PriceFeedCache.test.compiled.json +1 -1
- package/build/PriceFeedCache.test.permissions.compiled.json +1 -0
- package/build/Proxy.compiled.json +1 -1
- package/build/Proxy.permissions.test.compiled.json +1 -1
- package/build/Proxy.test.compiled.json +1 -1
- package/build/SmlConnection.compiled.json +1 -1
- package/build/SmlConnection.permissions.test.compiled.json +1 -1
- package/build/SmlConnection.test.compiled.json +1 -1
- package/build/SmlManager.compiled.json +1 -1
- package/build/SmlManager.permissions.test.compiled.json +1 -1
- package/build/SmlManager.test.compiled.json +1 -1
- package/build/Uln.compiled.json +1 -1
- package/build/Uln.test.compiled.json +1 -1
- package/build/UlnConnection.compiled.json +1 -1
- package/build/UlnConnection.test.compiled.json +1 -1
- package/build/UlnConnectionPermissions.test.compiled.json +1 -1
- package/build/UlnManagement.test.compiled.json +1 -1
- package/build/UlnManager.compiled.json +1 -1
- package/build/UlnManager.test.compiled.json +1 -1
- package/build/UlnManagerPermissions.test.compiled.json +1 -1
- package/build/UlnManagerUtil.test.compiled.json +1 -1
- package/build/UlnPermissions.test.compiled.json +1 -1
- package/build/UlnReceiveConfig.test.compiled.json +1 -1
- package/build/UlnSend.test.compiled.json +1 -1
- package/build/UlnSendConfig.test.compiled.json +1 -1
- package/build/UlnSendWithDvnFeeLib.test.compiled.json +1 -1
- package/build/UlnSendWithExecFeeLib.test.compiled.json +1 -1
- package/build/UlnSendWorkerFactory.test.compiled.json +1 -1
- package/build/UlnUtil.test.compiled.json +1 -1
- package/build/WorkerCore.test.compiled.json +1 -1
- package/build/badFeeLib1.test.compiled.json +1 -1
- package/build/badFeeLib10.test.compiled.json +1 -1
- package/build/badFeeLib11.test.compiled.json +1 -1
- package/build/badFeeLib12.test.compiled.json +1 -1
- package/build/badFeeLib2.test.compiled.json +1 -1
- package/build/badFeeLib3.test.compiled.json +1 -1
- package/build/badFeeLib4.test.compiled.json +1 -1
- package/build/badFeeLib5.test.compiled.json +1 -1
- package/build/badFeeLib6.test.compiled.json +1 -1
- package/build/badFeeLib7.test.compiled.json +1 -1
- package/build/badFeeLib8.test.compiled.json +1 -1
- package/build/badFeeLib9.test.compiled.json +1 -1
- package/package.json +1 -1
- package/src/funC++/classlib.fc +82 -65
- package/src/funC++/dataStructures/AddressList.fc +0 -1
- package/src/protocol/channel/storage.fc +1 -1
- package/src/protocol/endpoint/handler.fc +23 -7
- package/src/protocol/msglibs/ultralightnode/feeLibUtils.fc +2 -1
- package/src/protocol/msglibs/ultralightnode/uln/handler.fc +18 -10
- package/src/protocol/msglibs/ultralightnode/ulnConnection/handler.fc +5 -6
- package/src/protocol/msglibs/ultralightnode/ulnConnection/utils.fc +5 -1
- package/src/protocol/msglibs/ultralightnode/ulnManager/handler.fc +8 -5
- package/src/protocol/msglibs/ultralightnode/workerFeeLibs/dvnFeeLib/handler.fc +1 -1
- package/src/protocol/msglibs/ultralightnode/workerFeeLibs/executorFeeLib/handler.fc +3 -3
- package/src/workers/core/abstract/workerHandler.fc +1 -1
- package/src/workers/core/interface.fc +2 -2
- package/src/workers/dvn/handler.fc +30 -13
- package/src/workers/dvn/interface.fc +4 -6
- package/src/workers/dvn/storage.fc +6 -6
- package/src/workers/executor/handler.fc +2 -2
- package/src/workers/priceFeedCache/main.fc +1 -1
- package/src/workers/proxy/handler.fc +0 -2
- package/src/workers/msgdata/ProxyMessage.fc +0 -20
package/src/funC++/classlib.fc
CHANGED
|
@@ -14,7 +14,6 @@ const int cl::t::cellRef = 9;
|
|
|
14
14
|
const int cl::t::dict256 = cl::t::cellRef;
|
|
15
15
|
const int cl::t::objRef = cl::t::cellRef;
|
|
16
16
|
const int cl::t::addressList = cl::t::cellRef;
|
|
17
|
-
const int INVALID_TYPE = 13;
|
|
18
17
|
|
|
19
18
|
const int DICT256_KEYLEN = 256;
|
|
20
19
|
|
|
@@ -44,7 +43,6 @@ const int _HEADER_WIDTH = _BASIC_HEADER_WIDTH + _MAX_CLASS_FIELDS * _FIELD_INFO_
|
|
|
44
43
|
const int FIELD_TYPE_IDX = 0;
|
|
45
44
|
const int FIELD_VAL_IDX = 1;
|
|
46
45
|
|
|
47
|
-
|
|
48
46
|
;;; ====================== Class functions ======================
|
|
49
47
|
;; returns type width in bits
|
|
50
48
|
int _getTypeWidth(int clType) inline {
|
|
@@ -59,7 +57,7 @@ int cl::hash(cell $obj) impure inline {
|
|
|
59
57
|
return $obj.cell_hash();
|
|
60
58
|
}
|
|
61
59
|
|
|
62
|
-
int cl::
|
|
60
|
+
int cl::isNullObject(cell $obj) impure inline {
|
|
63
61
|
return $obj.cell_is_empty();
|
|
64
62
|
}
|
|
65
63
|
|
|
@@ -123,83 +121,95 @@ int cl::equalObjTypeShallow(cell $a, cell $b) {
|
|
|
123
121
|
}
|
|
124
122
|
|
|
125
123
|
int cl::typeof(cell $obj) inline method_id {
|
|
126
|
-
if (cl::
|
|
124
|
+
if (cl::isNullObject($obj)) {
|
|
127
125
|
return cl::NULL_CLASS_NAME;
|
|
128
126
|
}
|
|
129
127
|
return $obj.begin_parse().preload_uint(_NAME_WIDTH);
|
|
130
128
|
}
|
|
131
129
|
|
|
132
130
|
cell cl::declare(int name, tuple fields) inline {
|
|
131
|
+
;; Initialize a tuple with [null, empty_builder] to store cell builders
|
|
133
132
|
tuple classBuilder = unsafeTuple([null(), begin_cell()]);
|
|
134
133
|
|
|
134
|
+
;; Get number of fields of the object we want to create
|
|
135
135
|
int num_fields = fields.tlen();
|
|
136
|
+
;; Start building header with class name
|
|
136
137
|
builder headerBuilder = begin_cell().store_uint(name, _NAME_WIDTH);
|
|
137
138
|
|
|
138
|
-
;;
|
|
139
|
-
int curDataCell = 1;
|
|
140
|
-
int curRefCell = 1;
|
|
141
|
-
;;
|
|
142
|
-
int curCellMaxRefs = 2;
|
|
143
|
-
int curDataOffset = _HEADER_WIDTH;
|
|
144
|
-
int curRefOffset = 0;
|
|
139
|
+
;; Initialize tracking variables
|
|
140
|
+
int curDataCell = 1; ;; Current cell for storing data fields
|
|
141
|
+
int curRefCell = 1; ;; Current cell for storing reference fields
|
|
142
|
+
;; root node is special as it only allows two refs (1 for header, 1 for rest of obj)
|
|
143
|
+
int curCellMaxRefs = 2; ;; Max references allowed in current cell
|
|
144
|
+
int curDataOffset = _HEADER_WIDTH; ;; Current bit offset in data cell
|
|
145
|
+
int curRefOffset = 0; ;; Current reference offset in ref cell
|
|
145
146
|
|
|
147
|
+
;; Iterate through all fields
|
|
146
148
|
int curField = 0;
|
|
147
149
|
while (curField < num_fields) {
|
|
148
|
-
;;
|
|
149
|
-
;; loop management
|
|
150
|
+
;; Get current field and its type from tuple
|
|
150
151
|
tuple field = fields.tuple_at(curField);
|
|
151
152
|
int fieldType = field.int_at(FIELD_TYPE_IDX);
|
|
152
|
-
|
|
153
|
+
|
|
154
|
+
;; Get number of bits needed for this field type
|
|
155
|
+
;; (2^{bitLength} for uints, 0 for Refs)
|
|
153
156
|
int fieldBits = _getTypeWidth(fieldType);
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
curDataOffset
|
|
158
|
-
|
|
159
|
-
|
|
157
|
+
|
|
158
|
+
if (fieldBits > 0) {
|
|
159
|
+
;; If adding this integer field would exceed cell bit limit
|
|
160
|
+
if ((curDataOffset + fieldBits) > MAX_CELL_BITS) {
|
|
161
|
+
curDataCell += 1; ;; Move to next cell
|
|
162
|
+
curDataOffset = 0; ;; Reset bit offset
|
|
163
|
+
;; Add new cell builder if needed
|
|
164
|
+
if (curDataCell >= classBuilder.tlen()) {
|
|
165
|
+
classBuilder = classBuilder.tpush(begin_cell());
|
|
166
|
+
}
|
|
160
167
|
}
|
|
161
|
-
}
|
|
162
|
-
|
|
168
|
+
} else {
|
|
169
|
+
;; For reference types (fieldBits == 0)
|
|
170
|
+
;; If adding this ref would exceed cell ref limit
|
|
163
171
|
if ((curRefOffset + 1) > curCellMaxRefs) {
|
|
164
|
-
;;
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
172
|
+
curRefCell += 1; ;; Move to next cell
|
|
173
|
+
curRefOffset = 0; ;; Reset ref offset
|
|
174
|
+
curCellMaxRefs = MAX_CELL_REFS; ;; Use max refs for non-root cells
|
|
175
|
+
;; Add new cell builder if needed
|
|
168
176
|
if (curRefCell >= classBuilder.tlen()) {
|
|
169
177
|
classBuilder = classBuilder.tpush(begin_cell());
|
|
170
178
|
}
|
|
171
179
|
}
|
|
172
180
|
}
|
|
173
181
|
|
|
182
|
+
;; Store field value based on type
|
|
174
183
|
if (fieldType <= cl::t::address) {
|
|
184
|
+
;; For numeric types, store as uint
|
|
175
185
|
classBuilder = classBuilder.tset(
|
|
176
186
|
curDataCell,
|
|
177
187
|
cast_to_builder(classBuilder.at(curDataCell))
|
|
178
188
|
.store_uint(abs(field.int_at(FIELD_VAL_IDX)), fieldBits)
|
|
179
189
|
);
|
|
180
190
|
} elseif (fieldType == cl::t::objRef) {
|
|
191
|
+
;; For object references, store as ref
|
|
181
192
|
classBuilder = classBuilder.tset(
|
|
182
193
|
curRefCell,
|
|
183
194
|
cast_to_builder(classBuilder.at(curRefCell))
|
|
184
195
|
.store_ref(field.cell_at(FIELD_VAL_IDX))
|
|
185
196
|
);
|
|
186
197
|
} else {
|
|
187
|
-
|
|
188
|
-
classBuilder = classBuilder.tset(curRefCell,
|
|
189
|
-
cast_to_builder(classBuilder.at(curRefCell))
|
|
190
|
-
.store_ref(field_val)
|
|
191
|
-
);
|
|
198
|
+
throw(CLASSLIB::ERROR::INVALID_FIELD_TYPE);
|
|
192
199
|
}
|
|
193
200
|
|
|
201
|
+
;; Build field metadata in header
|
|
194
202
|
headerBuilder = headerBuilder
|
|
195
203
|
.store_uint(fieldType, _FIELD_TYPE_WIDTH);
|
|
196
204
|
if (fieldBits > 0) {
|
|
205
|
+
;; For data fields, store cell index, bit offset, and ref offset
|
|
197
206
|
headerBuilder = headerBuilder
|
|
198
207
|
.store_uint(curDataCell == 1 ? 0 : curDataCell, _CELL_ID_WIDTH)
|
|
199
208
|
.store_uint(curDataOffset, _DATA_OFFSET_WIDTH)
|
|
200
209
|
.store_uint(3, _REF_OFFSET_WIDTH);
|
|
201
210
|
curDataOffset += fieldBits;
|
|
202
211
|
} else {
|
|
212
|
+
;; For ref fields, store cell index and ref offset
|
|
203
213
|
headerBuilder = headerBuilder
|
|
204
214
|
.store_uint(curRefCell == 1 ? 0 : curRefCell, _CELL_ID_WIDTH)
|
|
205
215
|
.store_uint(MAX_CELL_BITS, _DATA_OFFSET_WIDTH)
|
|
@@ -209,9 +219,11 @@ cell cl::declare(int name, tuple fields) inline {
|
|
|
209
219
|
curField += 1;
|
|
210
220
|
}
|
|
211
221
|
|
|
212
|
-
|
|
222
|
+
;; Get root cell builder and count total cells
|
|
213
223
|
builder rootBuilder = classBuilder.at(1);
|
|
214
224
|
int numCells = classBuilder.tlen() - 1;
|
|
225
|
+
|
|
226
|
+
;; For multi-cell objects, ensure root has exactly 2 refs
|
|
215
227
|
if (numCells > 1) {
|
|
216
228
|
if (rootBuilder.builder_refs() == 0) {
|
|
217
229
|
rootBuilder = rootBuilder
|
|
@@ -223,10 +235,12 @@ cell cl::declare(int name, tuple fields) inline {
|
|
|
223
235
|
}
|
|
224
236
|
}
|
|
225
237
|
|
|
238
|
+
;; Finalize header and combine with root cell
|
|
226
239
|
headerBuilder = headerBuilder
|
|
227
240
|
.store_ones(_HEADER_WIDTH - headerBuilder.builder_bits())
|
|
228
241
|
.store_builder(rootBuilder);
|
|
229
242
|
|
|
243
|
+
;; Return final cell based on number of cells used
|
|
230
244
|
if (numCells == 1) {
|
|
231
245
|
return headerBuilder.end_cell();
|
|
232
246
|
}
|
|
@@ -247,37 +261,46 @@ cell cl::nullObject() inline method_id {
|
|
|
247
261
|
|
|
248
262
|
;;; ====================== Class Setter ======================
|
|
249
263
|
int cl::getFieldType::asm(slice self, int fieldInfoOffset) asm """
|
|
250
|
-
// STACK
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
264
|
+
// STACK: left -> right: bottom -> top //
|
|
265
|
+
// Setup // STACK [ headerSlice, fieldInfoOffset ]
|
|
266
|
+
4 PUSHINT // STACK [ headerSlice, fieldInfoOffset, _FIELD_TYPE_WIDTH ]
|
|
267
|
+
SDSUBSTR // STACK [ substring ]
|
|
268
|
+
4 PLDU // STACK [ 2BitUnsignInt ]
|
|
254
269
|
""";
|
|
255
270
|
|
|
256
271
|
int cl::getFieldCellIndex::asm(slice self, int fieldInfoOffset) asm """
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
2
|
|
272
|
+
// STACK: left -> right: bottom -> top //
|
|
273
|
+
// Setup // STACK [ headerSlice, fieldInfoOffset ]
|
|
274
|
+
4 ADDCONST // STACK [ headerSlice, fieldInfoOffset + _FIELD_TYPE_WIDTH ]
|
|
275
|
+
2 PUSHINT // STACK [ headerSlice, fieldInfoOffset + _FIELD_TYPE_WIDTH, _CELL_ID_WIDTH ]
|
|
276
|
+
SDSUBSTR // STACK [ substring ]
|
|
277
|
+
2 PLDU // STACK [ 2BitUnsignInt ]
|
|
261
278
|
""";
|
|
262
279
|
|
|
263
280
|
int cl::getFieldOffset::asm(slice self, int fieldInfoOffset) asm """
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
10
|
|
281
|
+
// STACK: left -> right: bottom -> top //
|
|
282
|
+
// Setup // STACK [ headerSlice, fieldInfoOffset ]
|
|
283
|
+
6 ADDCONST // STACK [ headerSlice, fieldInfoOffset + _FIELD_TYPE_WIDTH + _CELL_ID_WIDTH ]
|
|
284
|
+
10 PUSHINT // STACK [ headerSlice, fieldInfoOffset + _FIELD_TYPE_WIDTH + _CELL_ID_WIDTH, _DATA_OFFSET_WIDTH ]
|
|
285
|
+
SDSUBSTR // STACK [ substring ]
|
|
286
|
+
10 PLDU // STACK [ 10BitUnsignInt ]
|
|
268
287
|
""";
|
|
269
288
|
|
|
270
289
|
int cl::getFieldCellOffset::asm(slice self, int fieldInfoOffset) asm """
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
2
|
|
290
|
+
// STACK: left -> right: bottom -> top //
|
|
291
|
+
// Setup // STACK [ headerSlice, fieldInfoOffset ]
|
|
292
|
+
16 ADDCONST // STACK [ headerSlice, fieldInfoOffset + _FIELD_TYPE_WIDTH + _CELL_ID_WIDTH + _DATA_OFFSET_WIDTH ]
|
|
293
|
+
2 PUSHINT // STACK [ headerSlice, fieldInfoOffset + _FIELD_TYPE_WIDTH + _CELL_ID_WIDTH + _DATA_OFFSET_WIDTH, _REF_OFFSET_WIDTH ]
|
|
294
|
+
SDSUBSTR // STACK [ substring ]
|
|
295
|
+
2 PLDU // STACK [ 10BitUnsignInt ]
|
|
275
296
|
""";
|
|
276
297
|
|
|
277
298
|
int cl::preload_bits_offset_3::asm(int width1, slice self, int fieldOffset, int width2) asm """
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
299
|
+
// STACK: left -> right: bottom -> top //
|
|
300
|
+
// Setup // STACK [ width1, headerSlice, fieldOffset, width2 ]
|
|
301
|
+
SDSUBSTR // STACK [ width1, substring ]
|
|
302
|
+
s1 XCHG0 // STACK [ substring, width1 ]
|
|
303
|
+
PLDUX // STACK [ 10BitUnsignInt ] ( CC + 1 )
|
|
281
304
|
""";
|
|
282
305
|
|
|
283
306
|
forall X -> cell cl::set(cell $self, int fieldName, X val) inline method_id {
|
|
@@ -308,10 +331,6 @@ forall X -> cell cl::set(cell $self, int fieldName, X val) inline method_id {
|
|
|
308
331
|
replacement = replacement
|
|
309
332
|
.store_ref(val.cast_to_cell())
|
|
310
333
|
.store_slice(victim.scutlast(0, victim.slice_refs() - fieldRefsOffset - 1));
|
|
311
|
-
} elseif (fieldType == cl::t::objRef) {
|
|
312
|
-
replacement = replacement
|
|
313
|
-
.store_ref(val.cast_to_cell())
|
|
314
|
-
.store_slice(victim.scutlast(0, victim.slice_refs() - fieldRefsOffset - 1));
|
|
315
334
|
} else { ;; numeric type
|
|
316
335
|
replacement = replacement
|
|
317
336
|
.store_uint(abs(val.cast_to_int()), fieldWidth)
|
|
@@ -334,8 +353,6 @@ const int _NAME_WIDTH = 8 * MAX_NAME_LEN; ;; convert to bits
|
|
|
334
353
|
const int _BASIC_HEADER_WIDTH = _NAME_WIDTH;
|
|
335
354
|
const int MAX_NAME_INTLEN = (1 << (8 * MAX_NAME_LEN)) - 1;
|
|
336
355
|
|
|
337
|
-
const int _FIELD_TYPE_WIDTH+_CELL_ID_WIDTH = 6; ;; support up to 16 types
|
|
338
|
-
|
|
339
356
|
const int _FIELD_TYPE_WIDTH = 4; ;; support up to 16 types
|
|
340
357
|
const int _CELL_ID_WIDTH = 2; ;; the classlib backend supports up to 4 inner cells including root
|
|
341
358
|
const int _DATA_OFFSET_WIDTH = 10; ;; 1023 bits per cell = 2**10 - 1
|
|
@@ -361,9 +378,8 @@ int cl::get<uint>(cell $self, int fieldName, int width) inline method_id {
|
|
|
361
378
|
|
|
362
379
|
if (fieldCellIndex == 0) {
|
|
363
380
|
return cl::preload_bits_offset_3::asm(width, headerSlice, fieldOffset, width);
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
return cl::preload_bits_offset_3::asm( width, headerSlice.preload_ref_at(fieldCellIndex).begin_parse(), fieldOffset, width);
|
|
381
|
+
} else {
|
|
382
|
+
return cl::preload_bits_offset_3::asm(width, headerSlice.preload_ref_at(fieldCellIndex).begin_parse(), fieldOffset, width);
|
|
367
383
|
}
|
|
368
384
|
}
|
|
369
385
|
|
|
@@ -573,7 +589,7 @@ cell cl::dict256::New() inline {
|
|
|
573
589
|
|
|
574
590
|
(slice, int) cl::dict256::get(cell dict, int key) inline method_id {
|
|
575
591
|
if (dict.cell_is_empty()) {
|
|
576
|
-
return
|
|
592
|
+
return (null(), false);
|
|
577
593
|
}
|
|
578
594
|
return dict.udict_get?(DICT256_KEYLEN, key);
|
|
579
595
|
}
|
|
@@ -588,11 +604,11 @@ cell cl::dict256::New() inline {
|
|
|
588
604
|
|
|
589
605
|
(cell, int) cl::dict256::get<cellRef>(cell dict, int key) inline method_id {
|
|
590
606
|
if (dict.cell_is_empty()) {
|
|
591
|
-
return (
|
|
607
|
+
return (null(), false);
|
|
592
608
|
}
|
|
593
609
|
(cell ret, int exists) = dict.udict_get_ref?(DICT256_KEYLEN, key);
|
|
594
610
|
ifnot (exists) {
|
|
595
|
-
return (
|
|
611
|
+
return (null(), false);
|
|
596
612
|
}
|
|
597
613
|
return (ret, true);
|
|
598
614
|
}
|
|
@@ -607,6 +623,7 @@ cell cl::dict256::setRef(cell dict, int key, cell val) inline method_id {
|
|
|
607
623
|
}
|
|
608
624
|
return dict.udict_set_ref(DICT256_KEYLEN, key, val.cast_to_cell());
|
|
609
625
|
}
|
|
626
|
+
|
|
610
627
|
forall X -> cell cl::dict256::set(cell dict, int key, X val) inline {
|
|
611
628
|
slice _val = val.is_slice() ? val.cast_to_slice() : uint256ToSlice(val.cast_to_int());
|
|
612
629
|
if (dict.cell_is_empty()) {
|
|
@@ -740,7 +757,7 @@ cell cl::nestedDict256::delete(cell $self, int fieldName, int key) inline {
|
|
|
740
757
|
(cell, int) cl::nestedDict256::get<cellRef>(cell $self, int fieldName, int key) inline {
|
|
741
758
|
(slice s, int exists) = $self.cl::get<dict256>(fieldName).cl::dict256::get(key);
|
|
742
759
|
if (exists) {
|
|
743
|
-
return (s.preload_first_ref(),
|
|
760
|
+
return (s.preload_first_ref(), true);
|
|
744
761
|
}
|
|
745
|
-
return (
|
|
762
|
+
return (null(), false);
|
|
746
763
|
}
|
|
@@ -44,7 +44,6 @@ int AddressList::isValid(cell addressList, int maxCount) {
|
|
|
44
44
|
int count = 0;
|
|
45
45
|
while (addressListSlice.slice_empty?() == false) {
|
|
46
46
|
(int bits, int refs) = addressListSlice.slice_bits_refs();
|
|
47
|
-
;; todo: more test coverage
|
|
48
47
|
if ((refs > 1) | ((bits % 256) != 0)) {
|
|
49
48
|
return false;
|
|
50
49
|
}
|
|
@@ -44,7 +44,7 @@ cell Channel::New(int owner, cell $path, int endpointAddress) inline method_id {
|
|
|
44
44
|
[cl::t::address, endpointAddress], ;; Channel::endpointAddress
|
|
45
45
|
[cl::t::objRef, lz::EpConfig::NewWithDefaults()], ;; Channel::epConfigOApp
|
|
46
46
|
[cl::t::uint64, 0], ;; Channel::outboundNonce
|
|
47
|
-
[cl::t::dict256,
|
|
47
|
+
[cl::t::dict256, cl::dict256::New()], ;; Channel::sendRequestQueue
|
|
48
48
|
[cl::t::uint64, 0], ;; Channel::sendRequestId
|
|
49
49
|
[cl::t::objRef, POOO::New()], ;; Channel::commitPOOO
|
|
50
50
|
[cl::t::objRef, POOO::New()], ;; Channel::executePOOO
|
|
@@ -44,9 +44,9 @@
|
|
|
44
44
|
exists
|
|
45
45
|
);
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
throw_if(
|
|
48
48
|
Endpoint::ERROR::unresolvedMsglib,
|
|
49
|
-
|
|
49
|
+
cl::isNullObject($msglibInfo)
|
|
50
50
|
);
|
|
51
51
|
|
|
52
52
|
return (
|
|
@@ -106,7 +106,7 @@ cell _getEpConfigFromManagerAddresses(cell $setEpConfigMd, cell $path) inline me
|
|
|
106
106
|
|
|
107
107
|
(int, int) _getMsglibAndConnectionDefaults(int key, cell $path) inline method_id {
|
|
108
108
|
cell $msglibInfo = getContractStorage().cl::get<objRef>(key);
|
|
109
|
-
if (cl::
|
|
109
|
+
if (cl::isNullObject($msglibInfo)) {
|
|
110
110
|
return (NULLADDRESS, NULLADDRESS);
|
|
111
111
|
}
|
|
112
112
|
return (
|
|
@@ -250,6 +250,16 @@ tuple setEpConfigDefaults(cell $setEpConfigMd) impure inline method_id {
|
|
|
250
250
|
;; The extra gas cost is inconsequential because this is a configuration flow.
|
|
251
251
|
throw_if(validity, validity != lz::EpConfig::VALID);
|
|
252
252
|
|
|
253
|
+
if ($sendLibInfo.is_null()) {
|
|
254
|
+
$sendLibInfo = cl::nullObject();
|
|
255
|
+
}
|
|
256
|
+
if ($receiveLibInfo.is_null()) {
|
|
257
|
+
$receiveLibInfo = cl::nullObject();
|
|
258
|
+
}
|
|
259
|
+
if ($timeoutReceiveLibInfo.is_null()) {
|
|
260
|
+
$timeoutReceiveLibInfo = cl::nullObject();
|
|
261
|
+
}
|
|
262
|
+
|
|
253
263
|
setContractStorage(
|
|
254
264
|
$storage
|
|
255
265
|
.cl::set(Endpoint::defaultSendLibInfo, $sendLibInfo)
|
|
@@ -388,10 +398,7 @@ tuple addMsglib(cell $addMsglib) impure inline method_id {
|
|
|
388
398
|
)
|
|
389
399
|
.cl::set(Endpoint::numMsglibs, currentNumMsglibs + 1)
|
|
390
400
|
);
|
|
391
|
-
}
|
|
392
401
|
|
|
393
|
-
;; if the previous addMsglib ran out of gas, it can be retried
|
|
394
|
-
if ((~ exists) | $msglibInfo.cl::isNull()) {
|
|
395
402
|
;; Call the msglib manager to resolve the correct msglib contract
|
|
396
403
|
;; address for this endpoint's remote eid
|
|
397
404
|
actions~pushAction<call>(
|
|
@@ -399,6 +406,15 @@ tuple addMsglib(cell $addMsglib) impure inline method_id {
|
|
|
399
406
|
MsglibManager::OP::GET_MSGLIB_INFO,
|
|
400
407
|
$addMsglib
|
|
401
408
|
);
|
|
409
|
+
} else {
|
|
410
|
+
;; if the previous addMsglib ran out of gas, it can be retried
|
|
411
|
+
if (cl::isNullObject($msglibInfo)) {
|
|
412
|
+
actions~pushAction<call>(
|
|
413
|
+
msglibManagerAddress,
|
|
414
|
+
MsglibManager::OP::GET_MSGLIB_INFO,
|
|
415
|
+
$addMsglib
|
|
416
|
+
);
|
|
417
|
+
}
|
|
402
418
|
}
|
|
403
419
|
|
|
404
420
|
return actions;
|
|
@@ -416,7 +432,7 @@ tuple getMsglibInfoCallback(cell $msglibInfo) impure inline method_id {
|
|
|
416
432
|
getCaller()
|
|
417
433
|
);
|
|
418
434
|
|
|
419
|
-
throw_unless(Endpoint::ERROR::msglibInfoExists,
|
|
435
|
+
throw_unless(Endpoint::ERROR::msglibInfoExists, cl::isNullObject($storedMsglibInfo));
|
|
420
436
|
|
|
421
437
|
setContractStorage(
|
|
422
438
|
$storage.cl::nestedDict256::setRef(Endpoint::msglibs, getCaller(), $msglibInfo)
|
|
@@ -15,7 +15,8 @@ tuple safePackedInputsRunVm(
|
|
|
15
15
|
slice code,
|
|
16
16
|
int gasLimit
|
|
17
17
|
) impure method_id asm """
|
|
18
|
-
//
|
|
18
|
+
// STACK: left -> right: bottom -> top //
|
|
19
|
+
// Setup // STACK [ inputs, methodIdCRC, nOutputs, code, gasLimit ] ; len(callerStack) = 5
|
|
19
20
|
// // STACK [ ..., inputs, methodIdCRC, nOutputs, code, nOutputs, gasLimit ]
|
|
20
21
|
DEPTH 5 PUSHINT SUB // STACK [ ..., inputs, methodIdCRC, nOutputs, code, gasLimit, len(callerStack) ]
|
|
21
22
|
3 PUSHINT SETGLOBVAR // STACK [ ..., inputs, methodIdCRC, nOutputs, code, gasLimit ]
|
|
@@ -171,7 +171,7 @@ cell _removeWorker(cell $storage, cell $workerFeelibInfo) impure inline {
|
|
|
171
171
|
: Uln::remainingWorkerSlots;
|
|
172
172
|
return $storage
|
|
173
173
|
.cl::nestedDict256::delete(Uln::workerFeelibInfos, workerAddress)
|
|
174
|
-
.cl::set(
|
|
174
|
+
.cl::set(workerSlotField, $storage.cl::get<uint16>(workerSlotField) + 1);
|
|
175
175
|
}
|
|
176
176
|
|
|
177
177
|
(int, cell) _quoteWorker(
|
|
@@ -191,7 +191,7 @@ cell _removeWorker(cell $storage, cell $workerFeelibInfo) impure inline {
|
|
|
191
191
|
return (-1, null());
|
|
192
192
|
}
|
|
193
193
|
|
|
194
|
-
(cell $friendInfo, int friendExists) = ($workerInfo,
|
|
194
|
+
(cell $friendInfo, int friendExists) = ($workerInfo, true);
|
|
195
195
|
int friendWorkerAddress = $workerInfo
|
|
196
196
|
.cl::get<address>(UlnWorkerFeelibInfo::friendWorkerAddress);
|
|
197
197
|
|
|
@@ -387,6 +387,7 @@ cell _quoteWorkers(tuple args) impure inline method_id(23432) {
|
|
|
387
387
|
} elseif (
|
|
388
388
|
(op == Uln::OP::ULN_VERIFY)
|
|
389
389
|
| (op == Uln::OP::ULN_COMMIT_PACKET)
|
|
390
|
+
| (op == Uln::OP::ULN_QUOTE)
|
|
390
391
|
) {
|
|
391
392
|
return ();
|
|
392
393
|
} elseif (
|
|
@@ -547,7 +548,9 @@ tuple updateWorkerFeelib(cell $UlnWorkerFeelibInfo) impure inline method_id {
|
|
|
547
548
|
now()
|
|
548
549
|
);
|
|
549
550
|
|
|
550
|
-
setContractStorage(
|
|
551
|
+
setContractStorage(
|
|
552
|
+
$storage.cl::set(workerSlotField, remainingWorkerSlots - 1)
|
|
553
|
+
);
|
|
551
554
|
} else {
|
|
552
555
|
;; Do not allow workers to arbitrarily change their rent information
|
|
553
556
|
$UlnWorkerFeelibInfo = $UlnWorkerFeelibInfo
|
|
@@ -574,11 +577,10 @@ tuple updateWorkerFeelib(cell $UlnWorkerFeelibInfo) impure inline method_id {
|
|
|
574
577
|
tuple deregisterWorkerFeelib(cell $empty) impure inline method_id {
|
|
575
578
|
(cell $storage, tuple actions) = preamble();
|
|
576
579
|
|
|
577
|
-
int workerAddress = getCaller();
|
|
578
580
|
(cell $UlnWorkerFeelibInfo, int exists) = cl::nestedDict256::get<cellRef>(
|
|
579
581
|
$storage,
|
|
580
582
|
Uln::workerFeelibInfos,
|
|
581
|
-
workerAddress
|
|
583
|
+
getCaller() ;; = workerAddress
|
|
582
584
|
);
|
|
583
585
|
|
|
584
586
|
if (exists) {
|
|
@@ -599,10 +601,13 @@ tuple deregisterWorkerFeelib(cell $empty) impure inline method_id {
|
|
|
599
601
|
tuple setWorkerFeelibStorage(cell $newStorage) impure inline method_id {
|
|
600
602
|
(cell $storage, tuple actions) = preamble();
|
|
601
603
|
|
|
604
|
+
int workerAddress = getCaller();
|
|
605
|
+
|
|
602
606
|
(cell $workerInfo, int exists) = $storage.cl::nestedDict256::get<cellRef>(
|
|
603
607
|
Uln::workerFeelibInfos,
|
|
604
|
-
|
|
608
|
+
workerAddress
|
|
605
609
|
);
|
|
610
|
+
|
|
606
611
|
throw_unless(Uln::ERROR::nonexistentWorker, exists);
|
|
607
612
|
|
|
608
613
|
cell $updatedWorkerInfo = $workerInfo.cl::set(
|
|
@@ -617,7 +622,7 @@ tuple setWorkerFeelibStorage(cell $newStorage) impure inline method_id {
|
|
|
617
622
|
$storage
|
|
618
623
|
.cl::nestedDict256::setRef(
|
|
619
624
|
Uln::workerFeelibInfos,
|
|
620
|
-
|
|
625
|
+
workerAddress,
|
|
621
626
|
$updatedWorkerInfo
|
|
622
627
|
)
|
|
623
628
|
);
|
|
@@ -628,7 +633,7 @@ tuple setWorkerFeelibStorage(cell $newStorage) impure inline method_id {
|
|
|
628
633
|
);
|
|
629
634
|
|
|
630
635
|
actions~pushAction<call>(
|
|
631
|
-
|
|
636
|
+
workerAddress,
|
|
632
637
|
Uln::OP::SET_WORKER_FEELIB_STORAGE_CALLBACK,
|
|
633
638
|
$newStorage
|
|
634
639
|
);
|
|
@@ -682,7 +687,7 @@ tuple collectWorkerRent(cell $setAddress) impure inline method_id {
|
|
|
682
687
|
|
|
683
688
|
;; Admins do not pay rent
|
|
684
689
|
if ($workerInfo.cl::get<bool>(UlnWorkerFeelibInfo::isAdmin)) {
|
|
685
|
-
return
|
|
690
|
+
return actions;
|
|
686
691
|
}
|
|
687
692
|
|
|
688
693
|
int currentTimestamp = now();
|
|
@@ -693,7 +698,6 @@ tuple collectWorkerRent(cell $setAddress) impure inline method_id {
|
|
|
693
698
|
int currentRentBalance = $workerInfo.cl::get<coins>(UlnWorkerFeelibInfo::rentBalance);
|
|
694
699
|
|
|
695
700
|
;; if rentBalance is greater than totalRentOwed, we can update rentBalance and lastRentTimestamp
|
|
696
|
-
;; else we must delete(evict) the worker from the workerInfos
|
|
697
701
|
if (currentRentBalance >= totalRentOwed) {
|
|
698
702
|
$workerInfo = $workerInfo
|
|
699
703
|
.cl::set(UlnWorkerFeelibInfo::rentBalance, currentRentBalance - totalRentOwed)
|
|
@@ -707,6 +711,7 @@ tuple collectWorkerRent(cell $setAddress) impure inline method_id {
|
|
|
707
711
|
$workerInfo
|
|
708
712
|
);
|
|
709
713
|
} else {
|
|
714
|
+
;; else we must delete(evict) the worker from the workerInfos
|
|
710
715
|
setContractStorage(
|
|
711
716
|
_removeWorker($storage, $workerInfo)
|
|
712
717
|
);
|
|
@@ -751,6 +756,7 @@ tuple setDefaultUlnReceiveConfig(cell $ulnReceiveConfig) impure inline method_id
|
|
|
751
756
|
$sanitizedUlnReceiveConfig
|
|
752
757
|
)
|
|
753
758
|
);
|
|
759
|
+
|
|
754
760
|
actions~pushAction<event>(
|
|
755
761
|
Uln::event::ULN_DEFAULT_RECEIVE_CONFIG_SET,
|
|
756
762
|
$sanitizedUlnReceiveConfig
|
|
@@ -798,6 +804,8 @@ tuple garbageCollectInvalidAttestations(cell $mdAddress) impure inline method_id
|
|
|
798
804
|
return actions;
|
|
799
805
|
}
|
|
800
806
|
|
|
807
|
+
;; todo-thomas: I'm not sure if we can read tensors (or tuples for that matter)
|
|
808
|
+
;; from the view functions using the RPC call, maybe it should be one integer?
|
|
801
809
|
(int, int, int) version() impure method_id {
|
|
802
810
|
return (3, 0, 2);
|
|
803
811
|
}
|
|
@@ -99,7 +99,7 @@ int _committable(
|
|
|
99
99
|
nonce,
|
|
100
100
|
dvnAddress
|
|
101
101
|
);
|
|
102
|
-
if ($attestation.cl::
|
|
102
|
+
if ($attestation.cl::isNullObject()) {
|
|
103
103
|
return false;
|
|
104
104
|
}
|
|
105
105
|
if (
|
|
@@ -123,7 +123,7 @@ int _committable(
|
|
|
123
123
|
);
|
|
124
124
|
|
|
125
125
|
;; Nested if, else case is simply to do nothing
|
|
126
|
-
ifnot ($attestation.cl::
|
|
126
|
+
ifnot ($attestation.cl::isNullObject()) {
|
|
127
127
|
if (
|
|
128
128
|
($attestation.cl::get<uint64>(lz::Attestation::confirmations) >= requiredConfirmations)
|
|
129
129
|
& ($attestation.cl::get<uint256>(lz::Attestation::hash) == packetHash)
|
|
@@ -196,7 +196,7 @@ int verifiedView(int dvnAddress, int nonce, int packetHash, int requiredConfirma
|
|
|
196
196
|
dvnAddress
|
|
197
197
|
);
|
|
198
198
|
|
|
199
|
-
if ($attestation.cl::
|
|
199
|
+
if ($attestation.cl::isNullObject()) {
|
|
200
200
|
return false;
|
|
201
201
|
}
|
|
202
202
|
|
|
@@ -391,11 +391,10 @@ tuple garbageCollectInvalidAttestations(cell $mdObj) impure inline method_id {
|
|
|
391
391
|
cell $newStorage = UlnConnection::utils::deleteNonceAttestations($storage, nonce);
|
|
392
392
|
|
|
393
393
|
;; iterate the required DVNs
|
|
394
|
-
|
|
395
394
|
int requiredDVNAddress = requiredDVNsSlice~AddressList::next();
|
|
396
395
|
while (requiredDVNAddress > NULLADDRESS) {
|
|
397
396
|
cell $attestation = UlnConnection::utils::getHashLookup($storage, nonce, requiredDVNAddress);
|
|
398
|
-
ifnot (
|
|
397
|
+
ifnot (cl::isNullObject($attestation)) {
|
|
399
398
|
$newStorage = UlnConnection::utils::setHashLookup(
|
|
400
399
|
$newStorage,
|
|
401
400
|
nonce,
|
|
@@ -409,7 +408,7 @@ tuple garbageCollectInvalidAttestations(cell $mdObj) impure inline method_id {
|
|
|
409
408
|
int optionalDVNAddress = optionalDVNsSlice~AddressList::next();
|
|
410
409
|
while (optionalDVNAddress > NULLADDRESS) {
|
|
411
410
|
cell $attestation = UlnConnection::utils::getHashLookup($storage, nonce, optionalDVNAddress);
|
|
412
|
-
ifnot (
|
|
411
|
+
ifnot (cl::isNullObject($attestation)) {
|
|
413
412
|
$newStorage = UlnConnection::utils::setHashLookup(
|
|
414
413
|
$newStorage,
|
|
415
414
|
nonce,
|
|
@@ -31,7 +31,11 @@ cell UlnConnection::utils::setHashLookup(
|
|
|
31
31
|
cell $attestation
|
|
32
32
|
) impure inline {
|
|
33
33
|
cell hashLookups = $self.cl::get<dict256>(UlnConnection::hashLookups);
|
|
34
|
-
(cell addressLookup,
|
|
34
|
+
(cell addressLookup, int exists) = hashLookups.cl::dict256::get<cellRef>(nonce);
|
|
35
|
+
|
|
36
|
+
ifnot (exists) {
|
|
37
|
+
addressLookup = cl::dict256::New();
|
|
38
|
+
}
|
|
35
39
|
|
|
36
40
|
;; insert the attestation
|
|
37
41
|
addressLookup = addressLookup.cl::dict256::setRef(dvnAddress, $attestation);
|
|
@@ -113,7 +113,11 @@ int _getEventSink() impure inline {
|
|
|
113
113
|
int _calculateUlnAddress(cell $storage, int dstEid) impure inline method_id {
|
|
114
114
|
throw_if(UlnManager::ERROR::invalidEid, dstEid == 0);
|
|
115
115
|
return computeContractAddress(
|
|
116
|
-
Uln::New(
|
|
116
|
+
Uln::New(
|
|
117
|
+
getContractAddress(),
|
|
118
|
+
$storage.cl::get<uint32>(UlnManager::eid),
|
|
119
|
+
dstEid
|
|
120
|
+
),
|
|
117
121
|
$storage.cl::get<cellRef>(UlnManager::ulnCode)
|
|
118
122
|
);
|
|
119
123
|
}
|
|
@@ -321,7 +325,7 @@ tuple registerWorkerFeelibBytecode(cell $ulnWorkerFeelibBytecode) impure inline
|
|
|
321
325
|
cell $newStorage = $storage
|
|
322
326
|
.cl::nestedDict256::setRef(
|
|
323
327
|
UlnManager::workerFeelibBytecodes,
|
|
324
|
-
bytecode.
|
|
328
|
+
bytecode.cl::hash(),
|
|
325
329
|
bytecode
|
|
326
330
|
);
|
|
327
331
|
|
|
@@ -330,10 +334,10 @@ tuple registerWorkerFeelibBytecode(cell $ulnWorkerFeelibBytecode) impure inline
|
|
|
330
334
|
UlnManager::CONST::MAX_CUMULATIVE_BYTECODE_CELLS
|
|
331
335
|
);
|
|
332
336
|
|
|
333
|
-
setContractStorage($newStorage);
|
|
334
|
-
|
|
335
337
|
throw_unless(UlnManager::ERROR::feelibBytecodesExceeded, success);
|
|
336
338
|
|
|
339
|
+
setContractStorage($newStorage);
|
|
340
|
+
|
|
337
341
|
return actions;
|
|
338
342
|
}
|
|
339
343
|
|
|
@@ -438,7 +442,6 @@ tuple setUlnTreasuryFeeBps(cell $mdEid) impure inline method_id {
|
|
|
438
442
|
return actions;
|
|
439
443
|
}
|
|
440
444
|
|
|
441
|
-
|
|
442
445
|
;; This will override an existing tentative owner
|
|
443
446
|
;; Becuase we assert that the 'claimOwnership' can't be done by the 'null' address, it means
|
|
444
447
|
;; if we want to burn the ownership, we will need to set it to a contract which only has ability to
|