@layerzerolabs/layerzero-v2-ton 3.0.27 → 3.0.29

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 (200) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/build/ActionsSerde.test.compiled.json +1 -0
  3. package/build/AllStorages.compiled.json +1 -1
  4. package/build/AllStorages.test.compiled.json +1 -1
  5. package/build/BaseContract.test.compiled.json +1 -1
  6. package/build/Channel.compiled.json +1 -1
  7. package/build/Channel.permissions.test.compiled.json +1 -1
  8. package/build/ChannelBurn.test.compiled.json +1 -1
  9. package/build/ChannelCommitPacket.test.compiled.json +1 -1
  10. package/build/ChannelConfig.test.compiled.json +1 -1
  11. package/build/ChannelInitialize.test.compiled.json +1 -1
  12. package/build/ChannelMsglibIntegration.test.compiled.json +1 -1
  13. package/build/ChannelMsglibSendCallback.test.compiled.json +1 -1
  14. package/build/ChannelNilify.test.compiled.json +1 -1
  15. package/build/ChannelReceive.test.compiled.json +1 -1
  16. package/build/ChannelReceiveCallback.test.compiled.json +1 -1
  17. package/build/ChannelReceiveView.test.compiled.json +1 -1
  18. package/build/ChannelSend.test.compiled.json +1 -1
  19. package/build/ChannelSerde.test.compiled.json +1 -0
  20. package/build/Classlib.test.compiled.json +1 -1
  21. package/build/ComputeDataSizeGas.test.compiled.json +1 -1
  22. package/build/Connection.compiled.json +1 -1
  23. package/build/Controller.assertions.test.compiled.json +1 -1
  24. package/build/Controller.compiled.json +1 -1
  25. package/build/Controller.permissions.test.compiled.json +1 -1
  26. package/build/Controller.test.compiled.json +1 -1
  27. package/build/Counter.compiled.json +1 -1
  28. package/build/Counter.permissions.test.compiled.json +1 -1
  29. package/build/Counter.setters.test.compiled.json +1 -1
  30. package/build/Counter.test.compiled.json +1 -1
  31. package/build/Dvn.compiled.json +1 -1
  32. package/build/Dvn.test.compiled.json +1 -1
  33. package/build/DvnFeeLib.compiled.json +1 -1
  34. package/build/DvnFeeLibSerde.test.compiled.json +1 -0
  35. package/build/DvnPermissions.test.compiled.json +1 -1
  36. package/build/DvnSerde.test.compiled.json +1 -0
  37. package/build/Endpoint.compiled.json +1 -1
  38. package/build/Endpoint.permissions.test.compiled.json +1 -1
  39. package/build/Endpoint.test.compiled.json +1 -1
  40. package/build/EndpointSerde.test.compiled.json +1 -0
  41. package/build/EndpointSetEpConfigDefaults.test.compiled.json +1 -1
  42. package/build/Executor.compiled.json +1 -1
  43. package/build/Executor.test.compiled.json +1 -1
  44. package/build/ExecutorFeeLib.compiled.json +1 -1
  45. package/build/ExecutorFeeLibSerde.test.compiled.json +1 -0
  46. package/build/ExecutorPermissions.test.compiled.json +1 -1
  47. package/build/ExecutorSerde.test.compiled.json +1 -0
  48. package/build/LzClasses.test.compiled.json +1 -1
  49. package/build/LzClassesSerde.test.compiled.json +1 -0
  50. package/build/LzUtil.test.compiled.json +1 -1
  51. package/build/MsgData.test.compiled.json +1 -1
  52. package/build/MsgDataSerde.test.compiled.json +1 -0
  53. package/build/MsglibPacketCodec.test.compiled.json +1 -1
  54. package/build/PipelinedOutOfOrder.test.compiled.json +1 -1
  55. package/build/PipelinedOutOfOrderSerde.test.compiled.json +1 -0
  56. package/build/PriceFeedCache.compiled.json +1 -1
  57. package/build/PriceFeedCache.test.compiled.json +1 -1
  58. package/build/PriceFeedCache.test.permissions.compiled.json +1 -1
  59. package/build/PriceFeedCacheSerde.test.compiled.json +1 -0
  60. package/build/PriceFeedFeeLibSerde.test.compiled.json +1 -0
  61. package/build/Proxy.compiled.json +1 -1
  62. package/build/Proxy.permissions.test.compiled.json +1 -1
  63. package/build/Proxy.test.compiled.json +1 -1
  64. package/build/SmlConnection.compiled.json +1 -1
  65. package/build/SmlConnection.permissions.test.compiled.json +1 -1
  66. package/build/SmlConnection.test.compiled.json +1 -1
  67. package/build/SmlManager.compiled.json +1 -1
  68. package/build/SmlManager.permissions.test.compiled.json +1 -1
  69. package/build/SmlManager.test.compiled.json +1 -1
  70. package/build/Uln.compiled.json +1 -1
  71. package/build/Uln.test.compiled.json +1 -1
  72. package/build/UlnConnection.compiled.json +1 -1
  73. package/build/UlnConnection.test.compiled.json +1 -1
  74. package/build/UlnConnectionPermissions.test.compiled.json +1 -1
  75. package/build/UlnConnectionSerde.test.compiled.json +1 -0
  76. package/build/UlnManagement.test.compiled.json +1 -1
  77. package/build/UlnManager.compiled.json +1 -1
  78. package/build/UlnManager.test.compiled.json +1 -1
  79. package/build/UlnManagerPermissions.test.compiled.json +1 -1
  80. package/build/UlnManagerUtil.test.compiled.json +1 -1
  81. package/build/UlnMsgDataSerde.test.compiled.json +1 -0
  82. package/build/UlnPermissions.test.compiled.json +1 -1
  83. package/build/UlnReceiveConfig.test.compiled.json +1 -1
  84. package/build/UlnSend.test.compiled.json +1 -1
  85. package/build/UlnSendConfig.test.compiled.json +1 -1
  86. package/build/UlnSendWithDvnFeeLib.test.compiled.json +1 -1
  87. package/build/UlnSendWithExecFeeLib.test.compiled.json +1 -1
  88. package/build/UlnSendWorkerFactory.test.compiled.json +1 -1
  89. package/build/UlnSerde.test.compiled.json +1 -0
  90. package/build/UlnUtil.test.compiled.json +1 -1
  91. package/build/WorkerCore.test.compiled.json +1 -1
  92. package/build/WorkerCoreMsgDataSerde.test.compiled.json +1 -0
  93. package/build/WorkerCoreSerde.test.compiled.json +1 -0
  94. package/build/badFeeLib1.test.compiled.json +1 -1
  95. package/build/badFeeLib10.test.compiled.json +1 -1
  96. package/build/badFeeLib11.test.compiled.json +1 -1
  97. package/build/badFeeLib12.test.compiled.json +1 -1
  98. package/build/badFeeLib2.test.compiled.json +1 -1
  99. package/build/badFeeLib3.test.compiled.json +1 -1
  100. package/build/badFeeLib4.test.compiled.json +1 -1
  101. package/build/badFeeLib5.test.compiled.json +1 -1
  102. package/build/badFeeLib6.test.compiled.json +1 -1
  103. package/build/badFeeLib7.test.compiled.json +1 -1
  104. package/build/badFeeLib8.test.compiled.json +1 -1
  105. package/build/badFeeLib9.test.compiled.json +1 -1
  106. package/package.json +2 -1
  107. package/src/classes/lz/EpConfig.fc +90 -23
  108. package/src/classes/lz/MsglibInfo.fc +32 -5
  109. package/src/classes/lz/Packet.fc +109 -48
  110. package/src/classes/lz/Path.fc +55 -4
  111. package/src/classes/lz/ReceiveEpConfig.fc +36 -5
  112. package/src/classes/lz/SendEpConfig.fc +55 -5
  113. package/src/classes/msgdata/AddMsglib.fc +11 -0
  114. package/src/classes/msgdata/ChannelNonceInfo.fc +20 -0
  115. package/src/classes/msgdata/CoinsAmount.fc +8 -0
  116. package/src/classes/msgdata/Deploy.fc +19 -0
  117. package/src/classes/msgdata/ExtendedMd.fc +52 -1
  118. package/src/classes/msgdata/LzReceivePrepare.fc +21 -1
  119. package/src/classes/msgdata/LzReceiveStatus.fc +72 -1
  120. package/src/classes/msgdata/LzSend.fc +143 -24
  121. package/src/classes/msgdata/MdAddress.fc +42 -0
  122. package/src/classes/msgdata/MdEid.fc +8 -0
  123. package/src/classes/msgdata/MdObj.fc +32 -0
  124. package/src/classes/msgdata/MessagingReceipt.fc +34 -1
  125. package/src/classes/msgdata/MsglibSendCallback.fc +82 -0
  126. package/src/classes/msgdata/Nonce.fc +30 -0
  127. package/src/classes/msgdata/OptionsV1.fc +21 -1
  128. package/src/classes/msgdata/OptionsV2.fc +27 -0
  129. package/src/classes/msgdata/PacketId.fc +24 -0
  130. package/src/classes/msgdata/PacketSent.fc +35 -1
  131. package/src/classes/msgdata/SetAddress.fc +7 -0
  132. package/src/classes/msgdata/SetEpConfig.fc +17 -0
  133. package/src/funC++/actions/event.fc +17 -2
  134. package/src/funC++/actions/utils.fc +2 -2
  135. package/src/funC++/classlib.fc +33 -43
  136. package/src/funC++/constants.fc +28 -28
  137. package/src/funC++/dataStructures/PipelinedOutOfOrder.fc +75 -59
  138. package/src/funC++/stdlib.fc +26 -11
  139. package/src/funC++/testutils.fc +2 -2
  140. package/src/funC++/txnContext.fc +14 -14
  141. package/src/funC++/utils.fc +97 -1
  142. package/src/protocol/channel/handler.fc +247 -189
  143. package/src/protocol/channel/storage.fc +206 -1
  144. package/src/protocol/controller/handler.fc +35 -17
  145. package/src/protocol/controller/main.fc +1 -1
  146. package/src/protocol/core/abstract/protocolHandler.fc +11 -21
  147. package/src/protocol/core/baseStorage.fc +24 -0
  148. package/src/protocol/endpoint/handler.fc +99 -57
  149. package/src/protocol/endpoint/storage.fc +69 -5
  150. package/src/protocol/msglibs/BytesEncoder.fc +11 -10
  151. package/src/protocol/msglibs/simpleMsglib/smlManager/handler.fc +1 -4
  152. package/src/protocol/msglibs/ultralightnode/feeLibInterface.fc +1 -0
  153. package/src/protocol/msglibs/ultralightnode/msgdata/Attestation.fc +7 -8
  154. package/src/protocol/msglibs/ultralightnode/msgdata/DvnFeesPaidEvent.fc +20 -0
  155. package/src/protocol/msglibs/ultralightnode/msgdata/ExecutorFeePaidEvent.fc +15 -0
  156. package/src/protocol/msglibs/ultralightnode/msgdata/InitUln.fc +1 -1
  157. package/src/protocol/msglibs/ultralightnode/msgdata/InitUlnConnection.fc +1 -1
  158. package/src/protocol/msglibs/ultralightnode/msgdata/SetAdminWorkerAddresses.fc +6 -0
  159. package/src/protocol/msglibs/ultralightnode/msgdata/UlnEvents.fc +20 -0
  160. package/src/protocol/msglibs/ultralightnode/msgdata/UlnReceiveConfig.fc +114 -28
  161. package/src/protocol/msglibs/ultralightnode/msgdata/UlnSend.fc +51 -1
  162. package/src/protocol/msglibs/ultralightnode/msgdata/UlnSendConfig.fc +1 -1
  163. package/src/protocol/msglibs/ultralightnode/msgdata/UlnVerification.fc +10 -0
  164. package/src/protocol/msglibs/ultralightnode/msgdata/UlnWorkerFeelibBytecode.fc +6 -0
  165. package/src/protocol/msglibs/ultralightnode/msgdata/UlnWorkerFeelibInfo.fc +51 -1
  166. package/src/protocol/msglibs/ultralightnode/msgdata/VerificationStatus.fc +15 -0
  167. package/src/protocol/msglibs/ultralightnode/uln/handler.fc +84 -107
  168. package/src/protocol/msglibs/ultralightnode/uln/storage.fc +77 -1
  169. package/src/protocol/msglibs/ultralightnode/ulnConnection/handler.fc +92 -66
  170. package/src/protocol/msglibs/ultralightnode/ulnConnection/storage.fc +113 -6
  171. package/src/protocol/msglibs/ultralightnode/ulnConnection/utils.fc +6 -91
  172. package/src/protocol/msglibs/ultralightnode/ulnManager/handler.fc +55 -31
  173. package/src/protocol/msglibs/ultralightnode/workerFeeLibs/dvnFeeLib/handler.fc +13 -9
  174. package/src/protocol/msglibs/ultralightnode/workerFeeLibs/dvnFeeLib/storage.fc +23 -0
  175. package/src/protocol/msglibs/ultralightnode/workerFeeLibs/executorFeeLib/handler.fc +63 -27
  176. package/src/protocol/msglibs/ultralightnode/workerFeeLibs/executorFeeLib/storage.fc +19 -0
  177. package/src/protocol/msglibs/ultralightnode/workerFeeLibs/priceFeedFeeLib/storage.fc +55 -6
  178. package/src/workers/core/abstract/workerHandler.fc +20 -19
  179. package/src/workers/core/interface.fc +2 -1
  180. package/src/workers/core/workerCoreStorage.fc +16 -1
  181. package/src/workers/dvn/handler.fc +67 -26
  182. package/src/workers/dvn/storage.fc +15 -2
  183. package/src/workers/executor/handler.fc +18 -6
  184. package/src/workers/executor/interface.fc +1 -0
  185. package/src/workers/executor/storage.fc +8 -1
  186. package/src/workers/msgdata/DropEvent.fc +18 -0
  187. package/src/workers/msgdata/ExecuteParams.fc +66 -3
  188. package/src/workers/msgdata/NativeDrop.fc +4 -0
  189. package/src/workers/msgdata/SetDict.fc +6 -4
  190. package/src/workers/msgdata/SetQuorum.fc +4 -2
  191. package/src/workers/msgdata/SignedRequest.fc +8 -0
  192. package/src/workers/priceFeedCache/handler.fc +21 -27
  193. package/src/workers/priceFeedCache/storage.fc +16 -1
  194. package/src/workers/proxy/handler.fc +2 -1
  195. package/src/workers/proxy/storage.fc +1 -1
  196. package/tests/baseContractTest.fc +2 -6
  197. package/tests/baseSerdeTest.fc +117 -0
  198. package/tests/testMain.fc +2 -2
  199. package/src/classes/msgdata/Amount.fc +0 -16
  200. package/src/funC++/actions/destroy.fc +0 -27
@@ -64,21 +64,22 @@ int _getEventSink() impure inline {
64
64
  return getOwner();
65
65
  }
66
66
 
67
- () assertChannel(cell $md) impure inline {
67
+ () assertChannel() impure inline {
68
68
  throw_unless(
69
69
  UlnConnection::ERROR::onlyChannel,
70
- getCaller() == getContractStorage().cl::get<address>(UlnConnection::channelAddress)
70
+ getCaller() == getContractStorage().UlnConnection::getChannelAddress()
71
71
  );
72
72
  }
73
73
 
74
74
  () assertUln() impure inline {
75
75
  throw_unless(
76
76
  UlnConnection::ERROR::onlyUln,
77
- getCaller() == getContractStorage().cl::get<address>(UlnConnection::ulnAddress)
77
+ getCaller() == getContractStorage().UlnConnection::getUlnAddress()
78
78
  );
79
79
  }
80
80
 
81
81
  int _committable(
82
+ cell hashlookups,
82
83
  int nonce,
83
84
  int packetHash,
84
85
  cell requiredDVNs,
@@ -86,8 +87,6 @@ int _committable(
86
87
  int optionalDVNThreshold,
87
88
  int requiredConfirmations
88
89
  ) impure inline {
89
- cell $storage = getContractStorage();
90
-
91
90
  slice requiredDVNsSlice = requiredDVNs.begin_parse();
92
91
  ;; iterate through each of the required DVNs
93
92
 
@@ -95,16 +94,18 @@ int _committable(
95
94
 
96
95
  while (dvnAddress > NULLADDRESS) {
97
96
  cell $attestation = UlnConnection::utils::getHashLookup(
98
- $storage,
97
+ hashlookups,
99
98
  nonce,
100
99
  dvnAddress
101
100
  );
102
101
  if ($attestation.cl::isNullObject()) {
103
102
  return false;
104
103
  }
104
+
105
+ (int hash, int confirmations) = $attestation.lz::Attestation::deserialize();
105
106
  if (
106
- ($attestation.cl::get<uint64>(lz::Attestation::confirmations) < requiredConfirmations)
107
- | ($attestation.cl::get<uint256>(lz::Attestation::hash) != packetHash)
107
+ (confirmations < requiredConfirmations)
108
+ | (hash != packetHash)
108
109
  ) {
109
110
  return false;
110
111
  }
@@ -113,21 +114,24 @@ int _committable(
113
114
 
114
115
  int optionalDVNAttestations = 0;
115
116
 
117
+ if (optionalDVNThreshold == 0) {
118
+ ;; Short-circuit for the common case of 0 optional DVN
119
+ return true;
120
+ }
121
+
116
122
  slice optionalDVNsSlice = optionalDVNs.begin_parse();
117
123
  dvnAddress = optionalDVNsSlice~AddressList::next();
118
124
  while ((dvnAddress > NULLADDRESS) & (optionalDVNAttestations < optionalDVNThreshold)) {
119
125
  cell $attestation = UlnConnection::utils::getHashLookup(
120
- $storage,
126
+ hashlookups,
121
127
  nonce,
122
128
  dvnAddress
123
129
  );
124
130
 
125
131
  ;; Nested if, else case is simply to do nothing
126
132
  ifnot ($attestation.cl::isNullObject()) {
127
- if (
128
- ($attestation.cl::get<uint64>(lz::Attestation::confirmations) >= requiredConfirmations)
129
- & ($attestation.cl::get<uint256>(lz::Attestation::hash) == packetHash)
130
- ) {
133
+ (int hash, int confirmations) = $attestation.lz::Attestation::deserialize();
134
+ if ((confirmations >= requiredConfirmations) & (hash == packetHash)) {
131
135
  optionalDVNAttestations += 1;
132
136
  }
133
137
  }
@@ -144,8 +148,7 @@ int _committable(
144
148
  }
145
149
 
146
150
  int committableView(int nonce, cell $packet, cell $defaultUlnReceiveConfig) impure method_id {
147
- int firstUnexecutedNonce = getContractStorage()
148
- .cl::get<uint64>(UlnConnection::firstUnexecutedNonce);
151
+ int firstUnexecutedNonce = getContractStorage().cl::get<uint64>(UlnConnection::firstUnexecutedNonce);
149
152
  if (nonce < firstUnexecutedNonce) {
150
153
  return UlnConnection::verificationStatus::EXECUTED;
151
154
  }
@@ -176,7 +179,10 @@ int committableView(int nonce, cell $packet, cell $defaultUlnReceiveConfig) impu
176
179
  return UlnConnection::verificationStatus::CONFIGURATION_ERROR;
177
180
  }
178
181
 
182
+ cell hashLookups = getContractStorage().cl::get<dict256>(UlnConnection::hashLookups);
183
+
179
184
  if (_committable(
185
+ hashLookups,
180
186
  nonce,
181
187
  $packet.cl::hash(),
182
188
  requiredDVNs,
@@ -190,8 +196,9 @@ int committableView(int nonce, cell $packet, cell $defaultUlnReceiveConfig) impu
190
196
  }
191
197
 
192
198
  int verifiedView(int dvnAddress, int nonce, int packetHash, int requiredConfirmations) impure method_id {
199
+ cell hashLookups = getContractStorage().cl::get<dict256>(UlnConnection::hashLookups);
193
200
  cell $attestation = UlnConnection::utils::getHashLookup(
194
- getContractStorage(),
201
+ hashLookups,
195
202
  nonce,
196
203
  dvnAddress
197
204
  );
@@ -214,10 +221,7 @@ int _dvnIsRequiredOrOptional(slice requiredDVNsSlice, slice optionalDVNsSlice, i
214
221
  return AddressList::includes(dvnAddress, optionalDVNsSlice);
215
222
  }
216
223
 
217
- int _isDvnConfigured(int dvnAddress, cell $defaultUlnReceiveConfigOApp) impure inline {
218
- cell $customUlnReceiveConfigOApp = getContractStorage()
219
- .cl::get<objRef>(UlnConnection::UlnReceiveConfigOApp);
220
-
224
+ int _isDvnConfigured(int dvnAddress, cell $customUlnReceiveConfigOApp, cell $defaultUlnReceiveConfigOApp) impure inline {
221
225
  (cell requiredDVNs, cell optionalDVNs, int isValid) = UlnReceiveConfig::utils::getVerifyConfig(
222
226
  $customUlnReceiveConfigOApp,
223
227
  $defaultUlnReceiveConfigOApp
@@ -240,7 +244,7 @@ int _isDvnConfigured(int dvnAddress, cell $defaultUlnReceiveConfigOApp) impure i
240
244
  (op == MsglibConnection::OP::MSGLIB_CONNECTION_SEND)
241
245
  | (op == MsglibConnection::OP::MSGLIB_CONNECTION_COMMIT_PACKET_CALLBACK)
242
246
  ) {
243
- return assertChannel($md);
247
+ return assertChannel();
244
248
  } elseif (
245
249
  (op == UlnConnection::OP::ULN_CONNECTION_VERIFY)
246
250
  | (op == UlnConnection::OP::ULN_CONNECTION_COMMIT_PACKET)
@@ -253,7 +257,7 @@ int _isDvnConfigured(int dvnAddress, cell $defaultUlnReceiveConfigOApp) impure i
253
257
  } elseif (op == UlnConnection::OP::GARBAGE_COLLECT_INVALID_ATTESTATIONS){
254
258
  return assertUln();
255
259
  } elseif (op == MsglibConnection::OP::MSGLIB_CONNECTION_SYNC_CHANNEL_STATE) {
256
- return assertChannel($md);
260
+ return assertChannel();
257
261
  } elseif (
258
262
  (op == UlnConnection::OP::SET_OAPP_ULN_SEND_CONFIG)
259
263
  | (op == UlnConnection::OP::SET_OAPP_ULN_RECEIVE_CONFIG)
@@ -292,14 +296,20 @@ tuple msglibConnectionQuote(cell $lzSend) impure inline method_id {
292
296
  tuple msglibConnectionSend(cell $lzSend) impure inline method_id {
293
297
  (cell $storage, tuple actions) = preamble();
294
298
 
299
+ (
300
+ int ulnAddress,
301
+ int channelAddress,
302
+ cell $ulnSendConfigOApp
303
+ ) = $storage.UlnConnection::getSendInformation();
304
+
295
305
  actions~pushAction<call>(
296
- $storage.cl::get<address>(UlnConnection::ulnAddress),
306
+ ulnAddress,
297
307
  Uln::OP::ULN_SEND,
298
- md::UlnSend::New(
308
+ md::UlnSend::build(
299
309
  $lzSend,
300
- $storage.cl::get<objRef>(UlnConnection::UlnSendConfigOApp),
310
+ $ulnSendConfigOApp,
301
311
  getInitialStorage(),
302
- $storage.cl::get<address>(UlnConnection::channelAddress)
312
+ channelAddress
303
313
  )
304
314
  );
305
315
 
@@ -311,13 +321,24 @@ tuple msglibConnectionSend(cell $lzSend) impure inline method_id {
311
321
  tuple ulnConnectionVerify(cell $extendedMd) impure inline method_id {
312
322
  (cell $storage, tuple actions) = preamble();
313
323
 
314
- int dvnAddress = $extendedMd.cl::get<address>(md::ExtendedMd::forwardingAddress);
315
- cell $defaultUlnReceiveConfigOApp = $extendedMd.cl::get<objRef>(md::ExtendedMd::obj);
316
- cell $ulnVerification = $extendedMd.cl::get<objRef>(md::ExtendedMd::md);
324
+ cell $sanitizedExtendedMd = $extendedMd.md::ExtendedMd::sanitize();
317
325
 
318
- int nonce = $ulnVerification.cl::get<uint64>(md::UlnVerification::nonce);
326
+ (
327
+ cell $ulnVerification,
328
+ cell $defaultUlnReceiveConfigOApp,
329
+ int dvnAddress
330
+ ) = $sanitizedExtendedMd.md::ExtendedMd::deserialize();
319
331
 
320
- int firstUnexecutedNonce = $storage.cl::get<uint64>(UlnConnection::firstUnexecutedNonce);
332
+ (
333
+ int nonce,
334
+ cell $attestation
335
+ ) = $ulnVerification.md::UlnVerification::deserialize();
336
+
337
+ (
338
+ int firstUnexecutedNonce,
339
+ cell hashLookups,
340
+ cell $ulnReceiveConfigOApp
341
+ ) = $storage.UlnConnection::getVerifyInformation();
321
342
 
322
343
  ;; assume success unless something fails in the verification logic
323
344
  int statusCode = UlnConnection::ULN_CONNECTION_VERIFY_SUCCEEDED;
@@ -329,16 +350,16 @@ tuple ulnConnectionVerify(cell $extendedMd) impure inline method_id {
329
350
  ;; if the nonce has already been executed, or if it is invalid (== 0),
330
351
  ;; do not allow verification of the packet
331
352
  statusCode = UlnConnection::ULN_CONNECTION_VERIFY_FAILED::NONCE_OUT_OF_RANGE;
332
- } elseifnot (_isDvnConfigured(dvnAddress, $defaultUlnReceiveConfigOApp)) {
353
+ } elseifnot (_isDvnConfigured(dvnAddress, $ulnReceiveConfigOApp, $defaultUlnReceiveConfigOApp)) {
333
354
  statusCode = UlnConnection::ULN_CONNECTION_VERIFY_FAILED::DVN_NOT_CONFIGURED;
334
355
  } else {
335
- cell $attestation = $ulnVerification.cl::get<objRef>(md::UlnVerification::attestation);
336
356
  ;; Ensure the DVN is not passing a malicious attestation that is bigger than expected
337
357
  lz::Attestation::validate($attestation);
338
358
 
339
359
  setContractStorage(
340
360
  UlnConnection::utils::setHashLookup(
341
361
  $storage,
362
+ hashLookups,
342
363
  nonce,
343
364
  dvnAddress,
344
365
  $attestation
@@ -353,8 +374,8 @@ tuple ulnConnectionVerify(cell $extendedMd) impure inline method_id {
353
374
  actions~pushAction<call>(
354
375
  dvnAddress,
355
376
  UltraLightNode::OP::ULN_CONNECTION_VERIFY_CALLBACK,
356
- md::MdObj::New(
357
- md::VerificationStatus::New(nonce, statusCode),
377
+ md::MdObj::build(
378
+ md::VerificationStatus::build(nonce, statusCode),
358
379
  getInitialStorage()
359
380
  )
360
381
  );
@@ -366,10 +387,12 @@ tuple ulnConnectionVerify(cell $extendedMd) impure inline method_id {
366
387
  tuple garbageCollectInvalidAttestations(cell $mdObj) impure inline method_id {
367
388
  (cell $storage, tuple actions) = preamble();
368
389
 
369
- cell $mdNonce = $mdObj.cl::get<objRef>(md::MdObj::md);
390
+ cell $sanitizedMdObj = md::MdObj::sanitize($mdObj);
391
+
392
+ cell $mdNonce = $sanitizedMdObj.cl::get<objRef>(md::MdObj::md).md::Nonce::sanitize();
370
393
  int nonce = $mdNonce.cl::get<uint64>(md::Nonce::nonce);
371
394
 
372
- cell $defaultUlnReceiveConfigOApp = $mdObj.cl::get<objRef>(md::MdObj::obj);
395
+ cell $defaultUlnReceiveConfigOApp = $sanitizedMdObj.cl::get<objRef>(md::MdObj::obj);
373
396
 
374
397
  cell $customUlnReceiveConfigOApp = $storage.cl::get<objRef>(UlnConnection::UlnReceiveConfigOApp);
375
398
  (cell requiredDVNs, cell optionalDVNs, int isValid) = UlnReceiveConfig::utils::getVerifyConfig(
@@ -388,15 +411,18 @@ tuple garbageCollectInvalidAttestations(cell $mdObj) impure inline method_id {
388
411
  $mdNonce
389
412
  );
390
413
 
391
- cell $newStorage = UlnConnection::utils::deleteNonceAttestations($storage, nonce);
414
+ cell hashLookups = $storage.cl::get<dict256>(UlnConnection::hashLookups);
415
+
416
+ cell $newStorage = UlnConnection::utils::deleteNonceAttestations($storage, hashLookups, nonce);
392
417
 
393
418
  ;; iterate the required DVNs
394
419
  int requiredDVNAddress = requiredDVNsSlice~AddressList::next();
395
420
  while (requiredDVNAddress > NULLADDRESS) {
396
- cell $attestation = UlnConnection::utils::getHashLookup($storage, nonce, requiredDVNAddress);
421
+ cell $attestation = UlnConnection::utils::getHashLookup(hashLookups, nonce, requiredDVNAddress);
397
422
  ifnot (cl::isNullObject($attestation)) {
398
423
  $newStorage = UlnConnection::utils::setHashLookup(
399
424
  $newStorage,
425
+ hashLookups,
400
426
  nonce,
401
427
  requiredDVNAddress,
402
428
  $attestation
@@ -407,10 +433,11 @@ tuple garbageCollectInvalidAttestations(cell $mdObj) impure inline method_id {
407
433
 
408
434
  int optionalDVNAddress = optionalDVNsSlice~AddressList::next();
409
435
  while (optionalDVNAddress > NULLADDRESS) {
410
- cell $attestation = UlnConnection::utils::getHashLookup($storage, nonce, optionalDVNAddress);
436
+ cell $attestation = UlnConnection::utils::getHashLookup(hashLookups, nonce, optionalDVNAddress);
411
437
  ifnot (cl::isNullObject($attestation)) {
412
438
  $newStorage = UlnConnection::utils::setHashLookup(
413
439
  $newStorage,
440
+ hashLookups,
414
441
  nonce,
415
442
  optionalDVNAddress,
416
443
  $attestation
@@ -434,7 +461,7 @@ tuple garbageCollectExecutedNonces(cell $empty) impure inline method_id {
434
461
 
435
462
  if ((minNonce > 0) & (minNonce < firstUnexecutedNonce)) {
436
463
  setContractStorage(
437
- UlnConnection::utils::deleteNonceAttestations($storage, minNonce)
464
+ UlnConnection::utils::deleteNonceAttestations($storage, hashLookups, minNonce)
438
465
  );
439
466
  actions~pushAction<call>(
440
467
  getContractAddress(),
@@ -451,11 +478,15 @@ tuple garbageCollectExecutedNonces(cell $empty) impure inline method_id {
451
478
  tuple ulnConnectionCommitPacket(cell $mdObj) impure inline method_id {
452
479
  (cell $storage, tuple actions) = preamble();
453
480
 
454
- cell $packet = $mdObj.cl::get<objRef>(md::MdObj::md);
481
+ (cell $packet, cell $defaultUlnReceiveConfig) = $mdObj.md::MdObj::deserialize();
455
482
  int packetHash = $packet.cl::hash();
456
- int nonce = $packet.cl::get<uint64>(lz::Packet::nonce);
483
+ int nonce = $packet.lz::Packet::getNonce();
457
484
 
458
- cell $defaultUlnReceiveConfig = $mdObj.cl::get<objRef>(md::MdObj::obj);
485
+ (
486
+ int endpointAddress,
487
+ cell $ulnReceiveConfigOApp,
488
+ cell hashLookups
489
+ ) = $storage.UlnConnection::getCommitPacketInformation();
459
490
 
460
491
  (
461
492
  cell requiredDVNs,
@@ -465,7 +496,7 @@ tuple ulnConnectionCommitPacket(cell $mdObj) impure inline method_id {
465
496
  int commitPacketGas,
466
497
  int isValid
467
498
  ) = UlnReceiveConfig::utils::getCommitConfig(
468
- $storage.cl::get<objRef>(UlnConnection::UlnReceiveConfigOApp),
499
+ $ulnReceiveConfigOApp,
469
500
  $defaultUlnReceiveConfig
470
501
  );
471
502
 
@@ -474,8 +505,10 @@ tuple ulnConnectionCommitPacket(cell $mdObj) impure inline method_id {
474
505
  }
475
506
 
476
507
  ifnot (
477
- _committable(nonce,packetHash, requiredDVNs, optionalDVNs, optionalDVNThreshold, requiredConfirmations)
478
- & ((getMsgValue() - _gasToNanoton(get_gas_consumed())) >= _gasToNanoton(commitPacketGas))
508
+ _committable(hashLookups, nonce, packetHash, requiredDVNs, optionalDVNs, optionalDVNThreshold, requiredConfirmations)
509
+ & (
510
+ (getMsgValue() - _gasToNanoton(get_gas_consumed())) >= _gasToNanoton(commitPacketGas)
511
+ )
479
512
  ) {
480
513
  return actions;
481
514
  }
@@ -483,7 +516,7 @@ tuple ulnConnectionCommitPacket(cell $mdObj) impure inline method_id {
483
516
  ;; If all above checks pass (no early return)
484
517
  ;; commit the packet to the endpoint
485
518
  actions~pushAction<call>(
486
- $storage.cl::get<address>(UlnConnection::endpointAddress),
519
+ endpointAddress,
487
520
  Endpoint::OP::ENDPOINT_COMMIT_PACKET,
488
521
  $packet
489
522
  );
@@ -495,27 +528,15 @@ tuple ulnConnectionCommitPacket(cell $mdObj) impure inline method_id {
495
528
  tuple msglibConnectionCommitPacketCallback(cell $channelNonceInfo) impure inline method_id {
496
529
  (cell $storage, tuple actions) = preamble();
497
530
 
498
- int committedNonce = $channelNonceInfo.cl::get<uint64>(md::ChannelNonceInfo::nonce);
499
- ;; invariant:
500
- ;; firstUnexecutedNonce >= $storage.cl::get<uint64>(UlnConnection::firstUnexecutedNonce)
501
- int firstUnexecutedNonce = $channelNonceInfo
502
- .cl::get<uint64>(md::ChannelNonceInfo::firstUnexecutedNonce);
531
+ (int committedNonce, int firstUnexecutedNonce) = $channelNonceInfo.md::ChannelNonceInfo::deserialize();
503
532
 
504
- cell $commitPOOO = $storage.cl::get<objRef>(UlnConnection::commitPOOO);
533
+ cell $commitPOOO = $storage.UlnConnection::getCommitPOOO();
505
534
  if (committedNonce <= POOO::maxSettableBit($commitPOOO)) {
506
535
  $commitPOOO = POOO::set($commitPOOO, committedNonce);
507
536
  }
537
+
508
538
  setContractStorage(
509
- $storage
510
- .UlnConnection::utils::deleteNonceAttestations(committedNonce)
511
- .cl::set(
512
- UlnConnection::firstUnexecutedNonce,
513
- firstUnexecutedNonce
514
- )
515
- .cl::set(
516
- UlnConnection::commitPOOO,
517
- $commitPOOO
518
- )
539
+ $storage.UlnConnection::updateCommittmentInfo(committedNonce, firstUnexecutedNonce, $commitPOOO)
519
540
  );
520
541
 
521
542
  return actions;
@@ -524,11 +545,16 @@ tuple msglibConnectionCommitPacketCallback(cell $channelNonceInfo) impure inline
524
545
  ;; only channel
525
546
  tuple msglibConnectionSyncChannelState(cell $channelNonceInfo) impure inline method_id {
526
547
  (cell $storage, tuple actions) = preamble();
548
+
549
+ cell $sanitizedChannelNonceInfo = md::ChannelNonceInfo::sanitize($channelNonceInfo);
550
+
527
551
  ;; invariant:
528
552
  ;; firstUnexecutedNonce >= $storage.cl::get<uint64>(UlnConnection::firstUnexecutedNonce)
529
- int firstUnexecutedNonce = $channelNonceInfo
553
+ int firstUnexecutedNonce = $sanitizedChannelNonceInfo
530
554
  .cl::get<uint64>(md::ChannelNonceInfo::firstUnexecutedNonce);
531
- int firstUncommittedNonce = $channelNonceInfo.cl::get<uint64>(md::ChannelNonceInfo::nonce);
555
+ int firstUncommittedNonce = $sanitizedChannelNonceInfo
556
+ .cl::get<uint64>(md::ChannelNonceInfo::nonce);
557
+
532
558
  cell $commitPOOO = $storage.cl::get<objRef>(UlnConnection::commitPOOO);
533
559
  int maxNonce = POOO::maxSettableBit($commitPOOO);
534
560
 
@@ -16,17 +16,17 @@ const int UlnConnection::path = 1;
16
16
  ;; the channel address is set during the initialize call
17
17
  const int UlnConnection::endpointAddress = 2;
18
18
  const int UlnConnection::channelAddress = 3;
19
- const int UlnConnection::ulnAddress = 4;
19
+ const int UlnConnection::firstUnexecutedNonce = 4; ;; first nonce that has not been executed
20
+ const int UlnConnection::ulnAddress = 5;
20
21
 
21
22
  ;; EVM struct ExecutorConfig
22
23
  ;; uint32 maxMessageSize;
23
24
  ;; address executor;
24
- const int UlnConnection::UlnSendConfigOApp = 5; ;; UlnSendConfig
25
- const int UlnConnection::UlnReceiveConfigOApp = 6; ;; UlnReceiveConfig
25
+ const int UlnConnection::UlnSendConfigOApp = 6; ;; UlnSendConfig
26
+ const int UlnConnection::UlnReceiveConfigOApp = 7; ;; UlnReceiveConfig
26
27
  ;; breaking from EVM, we are using a fixed size array for the DVN verifications, and DVNs can
27
28
  ;; only verify a packet for a specific inbound nonce range.
28
- const int UlnConnection::hashLookups = 7; ;; map nonce -> map dvnAddress -> {hash,confirmations}
29
- const int UlnConnection::firstUnexecutedNonce = 8; ;; first nonce that has not been executed
29
+ const int UlnConnection::hashLookups = 8; ;; map nonce -> map dvnAddress -> {hash,confirmations}
30
30
  const int UlnConnection::commitPOOO = 9;
31
31
 
32
32
  ;; @owner ulnManager
@@ -38,12 +38,119 @@ cell UlnConnection::New(int owner, cell $path, int ulnAddress) method_id {
38
38
  [cl::t::objRef, $path], ;; UlnConnection::path
39
39
  [cl::t::address, NULLADDRESS], ;; UlnConnection::endpointAddress
40
40
  [cl::t::address, NULLADDRESS], ;; UlnConnection::channelAddress
41
+ [cl::t::uint64, 1], ;; UlnConnection::firstUnexecutedNonce
41
42
  [cl::t::address, ulnAddress], ;; UlnConnection::ulnAddress
42
43
  [cl::t::objRef, UlnSendConfig::NewWithDefaults()], ;; UlnConnection::UlnSendConfigOApp
43
44
  [cl::t::objRef, UlnReceiveConfig::NewWithDefaults()], ;; UlnConnection::UlnReceiveConfigOApp
44
45
  [cl::t::dict256, cl::dict256::New()], ;; UlnConnection::hashLookups
45
- [cl::t::uint64, 1], ;; UlnConnection::firstUnexecutedNonce
46
46
  [cl::t::objRef, empty_cell()] ;; UlnConnection::commitPOOO
47
47
  ])
48
48
  );
49
+ }
50
+
51
+ ;; ====================== Storage Accessors =====================
52
+
53
+
54
+ const int UlnConnection::_endpointAddressOffset = _HEADER_WIDTH;
55
+ const int UlnConnection::_channelAddressOffset = UlnConnection::_endpointAddressOffset + 256;
56
+ const int UlnConnection::_firstUnexecutedNonceOffset = UlnConnection::_channelAddressOffset + 256;
57
+ const int UlnConnection::_rootSliceBits = UlnConnection::_firstUnexecutedNonceOffset + 64;
58
+
59
+ const int UlnConnection::_ulnAddressOffset = 0;
60
+
61
+ cell UlnConnection::getBaseStorage(cell $self) impure inline {
62
+ return $self.cellPreloadRefAt(0);
63
+ }
64
+
65
+ int UlnConnection::getChannelAddress(cell $self) impure inline {
66
+ return $self.cellPreloadAddressAt(UlnConnection::_channelAddressOffset);
67
+ }
68
+
69
+ int UlnConnection::getUlnAddress(cell $self) impure inline {
70
+ return $self.cellPreloadRefAt(2).cellPreloadAddressAt(UlnConnection::_ulnAddressOffset);
71
+ }
72
+
73
+ cell UlnConnection::getCommitPOOO(cell $self) impure inline {
74
+ return $self.cellPreloadRefAt(2).cellPreloadRefAt(3);
75
+ }
76
+
77
+ ;; ====================== Composite Storage Accessors =====================
78
+
79
+ ;; (ulnAddress, channelAddress, ulnSendConfigOApp)
80
+ (int, int, cell) UlnConnection::getSendInformation(cell $self) impure inline {
81
+ slice selfSlice = $self.begin_parse();
82
+ slice ref2_slice = selfSlice.preloadRefSliceAt(2);
83
+ return (
84
+ ref2_slice.preloadAddressAt(UlnConnection::_ulnAddressOffset),
85
+ selfSlice.preloadAddressAt(UlnConnection::_channelAddressOffset),
86
+ ref2_slice.preloadRefAt(0)
87
+ );
88
+ }
89
+
90
+ ;; (firstUnexecutedNonce, hashLookups, ulnReceiveConfigOApp)
91
+ (int, cell, cell) UlnConnection::getVerifyInformation(cell $self) impure inline {
92
+ slice selfSlice = $self.begin_parse();
93
+ slice ref2Slice = selfSlice.preloadRefSliceAt(2);
94
+
95
+ return (
96
+ selfSlice.preloadUint64At(UlnConnection::_firstUnexecutedNonceOffset),
97
+ ref2Slice.preloadRefAt(2),
98
+ ref2Slice.preloadRefAt(1)
99
+ );
100
+ }
101
+
102
+ ;; (endpointAddress, ulnReceiveConfigOApp, hashLookups)
103
+ (int, cell, cell) UlnConnection::getCommitPacketInformation(cell $self) impure inline {
104
+ slice selfSlice = $self.begin_parse();
105
+ slice ref2Slice = selfSlice.preloadRefSliceAt(2);
106
+ return (
107
+ selfSlice.preloadAddressAt(UlnConnection::_endpointAddressOffset),
108
+ ref2Slice.preloadRefAt(1),
109
+ ref2Slice.preloadRefAt(2)
110
+ );
111
+ }
112
+
113
+ ;; ====================== Storage Modifiers =====================
114
+
115
+
116
+ cell UlnConnection::updateCommittmentInfo(
117
+ cell $self,
118
+ int committedNonce,
119
+ int firstUnexecutedNonce,
120
+ cell $commitPOOO
121
+ ) impure inline {
122
+ slice selfSlice = $self.begin_parse();
123
+
124
+ slice ref2Slice = selfSlice.preloadRefSliceAt(2);
125
+
126
+ cell hashLookups = ref2Slice.preloadRefAt(2).cl::dict256::delete(committedNonce);
127
+
128
+ cell new_ref2 = begin_cell()
129
+ .store_slice(ref2Slice.scutfirst(256, 2))
130
+ .store_ref(hashLookups)
131
+ .store_ref($commitPOOO)
132
+ .end_cell();
133
+
134
+ return begin_cell()
135
+ .store_slice(selfSlice.scutfirst(UlnConnection::_firstUnexecutedNonceOffset, 2))
136
+ .store_uint64(firstUnexecutedNonce)
137
+ .store_ref(new_ref2)
138
+ .end_cell();
139
+ }
140
+
141
+ cell UlnConnection::setHashLookups(cell $self, cell $hashLookups) impure inline {
142
+ slice selfSlice = $self.begin_parse();
143
+
144
+ slice originalStructuralCellSlice = selfSlice.preloadRefSliceAt(2);
145
+
146
+ cell newStructuralCell = begin_cell()
147
+ .store_slice(originalStructuralCellSlice.scutfirst(256, 2))
148
+ .store_ref($hashLookups)
149
+ .store_ref(originalStructuralCellSlice.preloadRefAt(3))
150
+ .end_cell();
151
+
152
+ return begin_cell()
153
+ .store_slice(selfSlice.scutfirst(UlnConnection::_rootSliceBits, 2))
154
+ .store_ref(newStructuralCell)
155
+ .end_cell();
49
156
  }
@@ -1,4 +1,5 @@
1
1
  #include "interface.fc";
2
+ #include "storage.fc";
2
3
 
3
4
  #include "../msgdata/Attestation.fc";
4
5
  #include "../msgdata/UlnReceiveConfig.fc";
@@ -6,9 +7,7 @@
6
7
 
7
8
  ;;; ===============================GETTERS===========================
8
9
 
9
- cell UlnConnection::utils::getHashLookup(cell $self, int nonce, int dvnAddress) impure inline {
10
- cell hashLookups = $self.cl::get<dict256>(UlnConnection::hashLookups);
11
-
10
+ cell UlnConnection::utils::getHashLookup(cell hashLookups, int nonce, int dvnAddress) impure inline {
12
11
  (cell addressLookup, int exists) = hashLookups.cl::dict256::get<cellRef>(nonce);
13
12
  ifnot (exists) {
14
13
  return cl::nullObject();
@@ -26,11 +25,11 @@ cell UlnConnection::utils::getHashLookup(cell $self, int nonce, int dvnAddress)
26
25
 
27
26
  cell UlnConnection::utils::setHashLookup(
28
27
  cell $self,
28
+ cell hashLookups,
29
29
  int nonce,
30
30
  int dvnAddress,
31
31
  cell $attestation
32
32
  ) impure inline {
33
- cell hashLookups = $self.cl::get<dict256>(UlnConnection::hashLookups);
34
33
  (cell addressLookup, int exists) = hashLookups.cl::dict256::get<cellRef>(nonce);
35
34
 
36
35
  ifnot (exists) {
@@ -41,97 +40,13 @@ cell UlnConnection::utils::setHashLookup(
41
40
  addressLookup = addressLookup.cl::dict256::setRef(dvnAddress, $attestation);
42
41
 
43
42
  ;; save the attestation hash
44
- return $self.cl::set(
45
- UlnConnection::hashLookups,
43
+ return $self.UlnConnection::setHashLookups(
46
44
  hashLookups.cl::dict256::setRef(nonce, addressLookup)
47
45
  );
48
46
  }
49
47
 
50
- cell UlnConnection::utils::deleteNonceAttestations(cell $self, int nonce) impure inline {
51
- cell hashLookups = $self.cl::get<dict256>(UlnConnection::hashLookups);
48
+ cell UlnConnection::utils::deleteNonceAttestations(cell $self, cell hashLookups, int nonce) impure inline {
52
49
  ;; delete is safe to call on a non-existent key
53
50
  hashLookups = hashLookups.cl::dict256::delete(nonce);
54
- return $self.cl::set(
55
- UlnConnection::hashLookups,
56
- hashLookups
57
- );
58
- }
59
-
60
- ;;; ===============================CHECKERS===========================
61
-
62
- ;; returns true if the attestations are valid (meets the dvn threshold and confirmations)
63
- int UlnConnection::utils::isCommittable(
64
- cell $self,
65
- cell $defaultUlnReceiveConfig,
66
- int nonce,
67
- int hash
68
- ) impure inline {
69
- cell hashLookups = $self.cl::get<dict256>(UlnConnection::hashLookups);
70
- (cell addressLookup, int exists) = hashLookups.cl::dict256::get<cellRef>(nonce);
71
- ifnot (exists) {
72
- return false;
73
- }
74
-
75
- ;; retrieve the DVNs from the config
76
- (
77
- cell requiredDVNs,
78
- cell optionalDVNs,
79
- int optionalDVNThreshold,
80
- int requiredConfirmations,
81
- _,
82
- int isValid
83
- ) = UlnReceiveConfig::utils::getCommitConfig(
84
- $self.cl::get<objRef>(UlnConnection::UlnReceiveConfigOApp),
85
- $defaultUlnReceiveConfig
86
- );
87
-
88
- ifnot (isValid) {
89
- return false;
90
- }
91
-
92
- slice requiredDVNsSlice = requiredDVNs.begin_parse();
93
- ;; iterate the requiredDVNs and make sure each has set the proper hash and confirmations
94
- int address = requiredDVNsSlice~AddressList::next();
95
- while (address > NULLADDRESS) {
96
- (cell $attestation, int exists) = addressLookup.cl::dict256::get<cellRef>(address);
97
- ;; if it doesn't exist it means we don't have the required DVN's attestation
98
- ifnot (exists) {
99
- return false;
100
- } elseifnot ($attestation.lz::Attestation::confirmable(hash, requiredConfirmations)) {
101
- ;; attestation hash...
102
- ;; (1) doesn't match the hash passed in
103
- ;; OR (2) the attestation confirmations are fewer than the required confirmations
104
- return false;
105
- }
106
- address = requiredDVNsSlice~AddressList::next();
107
- }
108
-
109
- if (optionalDVNThreshold == 0) {
110
- ;; if we don't have any optional DVNs, we're done
111
- return true;
112
- }
113
-
114
- slice optionalDVNsSlice = optionalDVNs.begin_parse();
115
- ;; iterate the optionalDVNs and make sure each has set the proper hash and confirmations
116
- int address = optionalDVNsSlice~AddressList::next();
117
- int count = 0;
118
-
119
- while (address > NULLADDRESS) {
120
- (cell $attestation, int attestationExists) = addressLookup.cl::dict256::get<cellRef>(address);
121
- ;; if the attestation matches the hash and is greater than or equal to the confirmations
122
- ;; we're looking for, increment the counter
123
- if (attestationExists) {
124
- if ($attestation.lz::Attestation::confirmable(hash, requiredConfirmations)) {
125
- count = count + 1;
126
- }
127
- if (count == optionalDVNThreshold) {
128
- ;; early exit if we hit the optional DVN threshold
129
- return true;
130
- }
131
- }
132
- address = optionalDVNsSlice~AddressList::next();
133
- }
134
-
135
- ;; threshold not met, return false
136
- return false;
51
+ return $self.UlnConnection::setHashLookups(hashLookups);
137
52
  }