@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.
Files changed (109) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/build/AllStorages.compiled.json +1 -1
  3. package/build/AllStorages.test.compiled.json +1 -1
  4. package/build/BaseContract.test.compiled.json +1 -1
  5. package/build/Channel.compiled.json +1 -1
  6. package/build/Channel.permissions.test.compiled.json +1 -1
  7. package/build/ChannelBurn.test.compiled.json +1 -1
  8. package/build/ChannelCommitPacket.test.compiled.json +1 -1
  9. package/build/ChannelConfig.test.compiled.json +1 -1
  10. package/build/ChannelInitialize.test.compiled.json +1 -1
  11. package/build/ChannelMsglibIntegration.test.compiled.json +1 -1
  12. package/build/ChannelMsglibSendCallback.test.compiled.json +1 -1
  13. package/build/ChannelNilify.test.compiled.json +1 -1
  14. package/build/ChannelReceive.test.compiled.json +1 -1
  15. package/build/ChannelReceiveCallback.test.compiled.json +1 -1
  16. package/build/ChannelReceiveView.test.compiled.json +1 -1
  17. package/build/ChannelSend.test.compiled.json +1 -1
  18. package/build/Classlib.test.compiled.json +1 -1
  19. package/build/ComputeDataSizeGas.test.compiled.json +1 -1
  20. package/build/Connection.compiled.json +1 -1
  21. package/build/Controller.assertions.test.compiled.json +1 -1
  22. package/build/Controller.compiled.json +1 -1
  23. package/build/Controller.permissions.test.compiled.json +1 -1
  24. package/build/Controller.test.compiled.json +1 -1
  25. package/build/Counter.compiled.json +1 -1
  26. package/build/Counter.permissions.test.compiled.json +1 -1
  27. package/build/Counter.setters.test.compiled.json +1 -1
  28. package/build/Counter.test.compiled.json +1 -1
  29. package/build/Dvn.compiled.json +1 -1
  30. package/build/Dvn.test.compiled.json +1 -1
  31. package/build/DvnFeeLib.compiled.json +1 -1
  32. package/build/DvnPermissions.test.compiled.json +1 -1
  33. package/build/Endpoint.compiled.json +1 -1
  34. package/build/Endpoint.permissions.test.compiled.json +1 -1
  35. package/build/Endpoint.test.compiled.json +1 -1
  36. package/build/EndpointSetEpConfigDefaults.test.compiled.json +1 -1
  37. package/build/Executor.compiled.json +1 -1
  38. package/build/Executor.test.compiled.json +1 -1
  39. package/build/ExecutorFeeLib.compiled.json +1 -1
  40. package/build/ExecutorPermissions.test.compiled.json +1 -1
  41. package/build/LzClasses.test.compiled.json +1 -1
  42. package/build/LzUtil.test.compiled.json +1 -1
  43. package/build/MsgData.test.compiled.json +1 -1
  44. package/build/MsglibPacketCodec.test.compiled.json +1 -1
  45. package/build/PipelinedOutOfOrder.test.compiled.json +1 -1
  46. package/build/PriceFeedCache.compiled.json +1 -1
  47. package/build/PriceFeedCache.test.compiled.json +1 -1
  48. package/build/PriceFeedCache.test.permissions.compiled.json +1 -0
  49. package/build/Proxy.compiled.json +1 -1
  50. package/build/Proxy.permissions.test.compiled.json +1 -1
  51. package/build/Proxy.test.compiled.json +1 -1
  52. package/build/SmlConnection.compiled.json +1 -1
  53. package/build/SmlConnection.permissions.test.compiled.json +1 -1
  54. package/build/SmlConnection.test.compiled.json +1 -1
  55. package/build/SmlManager.compiled.json +1 -1
  56. package/build/SmlManager.permissions.test.compiled.json +1 -1
  57. package/build/SmlManager.test.compiled.json +1 -1
  58. package/build/Uln.compiled.json +1 -1
  59. package/build/Uln.test.compiled.json +1 -1
  60. package/build/UlnConnection.compiled.json +1 -1
  61. package/build/UlnConnection.test.compiled.json +1 -1
  62. package/build/UlnConnectionPermissions.test.compiled.json +1 -1
  63. package/build/UlnManagement.test.compiled.json +1 -1
  64. package/build/UlnManager.compiled.json +1 -1
  65. package/build/UlnManager.test.compiled.json +1 -1
  66. package/build/UlnManagerPermissions.test.compiled.json +1 -1
  67. package/build/UlnManagerUtil.test.compiled.json +1 -1
  68. package/build/UlnPermissions.test.compiled.json +1 -1
  69. package/build/UlnReceiveConfig.test.compiled.json +1 -1
  70. package/build/UlnSend.test.compiled.json +1 -1
  71. package/build/UlnSendConfig.test.compiled.json +1 -1
  72. package/build/UlnSendWithDvnFeeLib.test.compiled.json +1 -1
  73. package/build/UlnSendWithExecFeeLib.test.compiled.json +1 -1
  74. package/build/UlnSendWorkerFactory.test.compiled.json +1 -1
  75. package/build/UlnUtil.test.compiled.json +1 -1
  76. package/build/WorkerCore.test.compiled.json +1 -1
  77. package/build/badFeeLib1.test.compiled.json +1 -1
  78. package/build/badFeeLib10.test.compiled.json +1 -1
  79. package/build/badFeeLib11.test.compiled.json +1 -1
  80. package/build/badFeeLib12.test.compiled.json +1 -1
  81. package/build/badFeeLib2.test.compiled.json +1 -1
  82. package/build/badFeeLib3.test.compiled.json +1 -1
  83. package/build/badFeeLib4.test.compiled.json +1 -1
  84. package/build/badFeeLib5.test.compiled.json +1 -1
  85. package/build/badFeeLib6.test.compiled.json +1 -1
  86. package/build/badFeeLib7.test.compiled.json +1 -1
  87. package/build/badFeeLib8.test.compiled.json +1 -1
  88. package/build/badFeeLib9.test.compiled.json +1 -1
  89. package/package.json +1 -1
  90. package/src/funC++/classlib.fc +82 -65
  91. package/src/funC++/dataStructures/AddressList.fc +0 -1
  92. package/src/protocol/channel/storage.fc +1 -1
  93. package/src/protocol/endpoint/handler.fc +23 -7
  94. package/src/protocol/msglibs/ultralightnode/feeLibUtils.fc +2 -1
  95. package/src/protocol/msglibs/ultralightnode/uln/handler.fc +18 -10
  96. package/src/protocol/msglibs/ultralightnode/ulnConnection/handler.fc +5 -6
  97. package/src/protocol/msglibs/ultralightnode/ulnConnection/utils.fc +5 -1
  98. package/src/protocol/msglibs/ultralightnode/ulnManager/handler.fc +8 -5
  99. package/src/protocol/msglibs/ultralightnode/workerFeeLibs/dvnFeeLib/handler.fc +1 -1
  100. package/src/protocol/msglibs/ultralightnode/workerFeeLibs/executorFeeLib/handler.fc +3 -3
  101. package/src/workers/core/abstract/workerHandler.fc +1 -1
  102. package/src/workers/core/interface.fc +2 -2
  103. package/src/workers/dvn/handler.fc +30 -13
  104. package/src/workers/dvn/interface.fc +4 -6
  105. package/src/workers/dvn/storage.fc +6 -6
  106. package/src/workers/executor/handler.fc +2 -2
  107. package/src/workers/priceFeedCache/main.fc +1 -1
  108. package/src/workers/proxy/handler.fc +0 -2
  109. package/src/workers/msgdata/ProxyMessage.fc +0 -20
@@ -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::isNull(cell $obj) impure inline {
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::isNull($obj)) {
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
- ;; Loop indices
139
- int curDataCell = 1;
140
- int curRefCell = 1;
141
- ;; allow one direct ref in the root cell
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
- if ((curDataOffset + fieldBits) > MAX_CELL_BITS) {
155
- ;; move to the next cell
156
- curDataCell += 1;
157
- curDataOffset = 0;
158
- if (curDataCell >= classBuilder.tlen()) {
159
- classBuilder = classBuilder.tpush(begin_cell());
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
- if (fieldBits == 0) {
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
- ;; move to the next cell
165
- curRefCell += 1;
166
- curRefOffset = 0;
167
- curCellMaxRefs = MAX_CELL_REFS;
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
- cell field_val = field.cell_at(FIELD_VAL_IDX);
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 [fieldInfoOffset, headerSlice]
251
- 4 PUSHINT // STACK [_FIELD_TYPE_WIDTH, fieldInfoOffset, headerSlice]
252
- SDSUBSTR // STACK [substring]
253
- 4 PLDU // STACK [2BitUnsignInt]
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
- 4 ADDCONST // STACK [fieldInfoOffset + _FIELD_TYPE_WIDTH, headerSlice]
258
- 2 PUSHINT // STACK [_CELL_ID_WIDTH, fieldInfoOffset + _FIELD_TYPE_WIDTH, headerSlice]
259
- SDSUBSTR // STACK [substring]
260
- 2 PLDU // STACK [2BitUnsignInt]
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
- 6 ADDCONST // STACK [fieldInfoOffset + _FIELD_TYPE_WIDTH + _CELL_ID_WIDTH, headerSlice]
265
- 10 PUSHINT // STACK [_DATA_OFFSET_WIDTH, fieldInfoOffset +_FIELD_TYPE_WIDTH + _CELL_ID_WIDTH, headerSlice]
266
- SDSUBSTR // STACK [substring]
267
- 10 PLDU // STACK [10BitUnsignInt]
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
- 16 ADDCONST // STACK [fieldInfoOffset + _FIELD_TYPE_WIDTH + _CELL_ID_WIDTH + _DATA_OFFSET_WIDTH, headerSlice]
272
- 2 PUSHINT // STACK [_REF_OFFSET_WIDTH, fieldInfoOffset + _FIELD_TYPE_WIDTH + _CELL_ID_WIDTH + _DATA_OFFSET_WIDTH headerSlice]
273
- SDSUBSTR // STACK [substring]
274
- 2 PLDU // STACK [10BitUnsignInt]
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
- SDSUBSTR // STACK [substring]
279
- s1 XCHG0
280
- PLDUX // STACK [10BitUnsignInt] (CC +1 )
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
- else {
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 new_dict().udict_get?(DICT256_KEYLEN, key);
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 (empty_cell(), false);
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 (empty_cell(), false);
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(), exists);
760
+ return (s.preload_first_ref(), true);
744
761
  }
745
- return (empty_cell(), exists);
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, empty_cell()], ;; Channel::sendRequestQueue
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
- throw_unless(
47
+ throw_if(
48
48
  Endpoint::ERROR::unresolvedMsglib,
49
- $msglibInfo.cl::hash() != cl::nullObject().cl::hash()
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::isNull($msglibInfo)) {
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, $storedMsglibInfo.cl::isNull());
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
- // Setup // callerStack: [ inputs, methodIdCRC, nOutputs, code, gasLimit ] ; len(callerStack) = 5
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( workerSlotField, $storage.cl::get<uint16>(workerSlotField) + 1);
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, workerExists);
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($storage.cl::set(workerSlotField, remainingWorkerSlots - 1));
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
- getCaller()
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
- getCaller(),
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
- getCaller(),
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 emptyActions();
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::isNull()) {
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::isNull()) {
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::isNull()) {
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 ($attestation.cl::isNull()) {
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 ($attestation.cl::isNull()) {
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, _) = hashLookups.cl::dict256::get<cellRef>(nonce);
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(getContractAddress(), $storage.cl::get<uint32>(UlnManager::eid), dstEid),
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.cell_hash(),
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
@@ -17,7 +17,7 @@ const int DvnFeelib::VERIFY_BYTES_ULN = 288;
17
17
  if (
18
18
  (cl::typeof($options) == md::OptionsV1::NAME)
19
19
  | (cl::typeof($options) == md::OptionsV2::NAME)
20
- | cl::isNull($options)
20
+ | cl::isNullObject($options)
21
21
  ) {
22
22
  return ();
23
23
  } else {