@layerzerolabs/protocol-stellar-v2 0.2.8

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 (265) hide show
  1. package/.turbo/turbo-build.log +727 -0
  2. package/.turbo/turbo-lint.log +158 -0
  3. package/.turbo/turbo-test.log +796 -0
  4. package/Cargo.lock +2237 -0
  5. package/Cargo.toml +63 -0
  6. package/clippy.toml +7 -0
  7. package/contracts/common-macros/Cargo.toml +20 -0
  8. package/contracts/common-macros/src/error.rs +53 -0
  9. package/contracts/common-macros/src/event.rs +16 -0
  10. package/contracts/common-macros/src/lib.rs +255 -0
  11. package/contracts/common-macros/src/ownable.rs +63 -0
  12. package/contracts/common-macros/src/snapshots/common_macros__tests__tests__snapshot_generated_storage_code.snap +310 -0
  13. package/contracts/common-macros/src/storage.rs +439 -0
  14. package/contracts/common-macros/src/tests.rs +287 -0
  15. package/contracts/common-macros/src/ttl_configurable.rs +60 -0
  16. package/contracts/endpoint-v2/ARCHITECTURE.md +233 -0
  17. package/contracts/endpoint-v2/Cargo.toml +30 -0
  18. package/contracts/endpoint-v2/src/constants.rs +52 -0
  19. package/contracts/endpoint-v2/src/endpoint_v2.rs +305 -0
  20. package/contracts/endpoint-v2/src/errors.rs +29 -0
  21. package/contracts/endpoint-v2/src/events.rs +207 -0
  22. package/contracts/endpoint-v2/src/interfaces/layerzero_composer.rs +26 -0
  23. package/contracts/endpoint-v2/src/interfaces/layerzero_endpoint_v2.rs +170 -0
  24. package/contracts/endpoint-v2/src/interfaces/layerzero_receiver.rs +43 -0
  25. package/contracts/endpoint-v2/src/interfaces/message_lib.rs +62 -0
  26. package/contracts/endpoint-v2/src/interfaces/message_lib_manager.rs +220 -0
  27. package/contracts/endpoint-v2/src/interfaces/messaging_channel.rs +121 -0
  28. package/contracts/endpoint-v2/src/interfaces/messaging_composer.rs +63 -0
  29. package/contracts/endpoint-v2/src/interfaces/mod.rs +17 -0
  30. package/contracts/endpoint-v2/src/interfaces/send_lib.rs +70 -0
  31. package/contracts/endpoint-v2/src/lib.rs +22 -0
  32. package/contracts/endpoint-v2/src/message_lib_manager.rs +315 -0
  33. package/contracts/endpoint-v2/src/messaging_channel.rs +218 -0
  34. package/contracts/endpoint-v2/src/messaging_composer.rs +76 -0
  35. package/contracts/endpoint-v2/src/storage.rs +78 -0
  36. package/contracts/endpoint-v2/src/tests/endpoint_setup.rs +131 -0
  37. package/contracts/endpoint-v2/src/tests/endpoint_v2/clear.rs +237 -0
  38. package/contracts/endpoint-v2/src/tests/endpoint_v2/delegate.rs +42 -0
  39. package/contracts/endpoint-v2/src/tests/endpoint_v2/initializable.rs +76 -0
  40. package/contracts/endpoint-v2/src/tests/endpoint_v2/lz_receive_alert.rs +211 -0
  41. package/contracts/endpoint-v2/src/tests/endpoint_v2/mod.rs +18 -0
  42. package/contracts/endpoint-v2/src/tests/endpoint_v2/native_token.rs +10 -0
  43. package/contracts/endpoint-v2/src/tests/endpoint_v2/owner.rs +10 -0
  44. package/contracts/endpoint-v2/src/tests/endpoint_v2/pay_messaging_fees.rs +424 -0
  45. package/contracts/endpoint-v2/src/tests/endpoint_v2/quote.rs +144 -0
  46. package/contracts/endpoint-v2/src/tests/endpoint_v2/recover_token.rs +72 -0
  47. package/contracts/endpoint-v2/src/tests/endpoint_v2/require_oapp_auth.rs +29 -0
  48. package/contracts/endpoint-v2/src/tests/endpoint_v2/send.rs +513 -0
  49. package/contracts/endpoint-v2/src/tests/endpoint_v2/set_delegate.rs +43 -0
  50. package/contracts/endpoint-v2/src/tests/endpoint_v2/set_zro.rs +27 -0
  51. package/contracts/endpoint-v2/src/tests/endpoint_v2/transfer_ownership.rs +30 -0
  52. package/contracts/endpoint-v2/src/tests/endpoint_v2/ttl_config.rs +202 -0
  53. package/contracts/endpoint-v2/src/tests/endpoint_v2/verifiable.rs +59 -0
  54. package/contracts/endpoint-v2/src/tests/endpoint_v2/verify.rs +172 -0
  55. package/contracts/endpoint-v2/src/tests/endpoint_v2/zro.rs +23 -0
  56. package/contracts/endpoint-v2/src/tests/message_lib_manager/mod.rs +10 -0
  57. package/contracts/endpoint-v2/src/tests/message_lib_manager/register_library.rs +131 -0
  58. package/contracts/endpoint-v2/src/tests/message_lib_manager/require_registered.rs +35 -0
  59. package/contracts/endpoint-v2/src/tests/message_lib_manager/require_supported_eid.rs +28 -0
  60. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_config.rs +79 -0
  61. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_default_receive_lib_timeout.rs +246 -0
  62. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_default_receive_library.rs +285 -0
  63. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_default_send_library.rs +180 -0
  64. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_receive_library.rs +405 -0
  65. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_receive_library_timeout.rs +80 -0
  66. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_send_library.rs +131 -0
  67. package/contracts/endpoint-v2/src/tests/messaging_channel/burn.rs +358 -0
  68. package/contracts/endpoint-v2/src/tests/messaging_channel/clear.rs +316 -0
  69. package/contracts/endpoint-v2/src/tests/messaging_channel/inbound_nonce.rs +288 -0
  70. package/contracts/endpoint-v2/src/tests/messaging_channel/inbound_payload_hash.rs +316 -0
  71. package/contracts/endpoint-v2/src/tests/messaging_channel/internal.rs +388 -0
  72. package/contracts/endpoint-v2/src/tests/messaging_channel/lazy_inbound_nonce.rs +307 -0
  73. package/contracts/endpoint-v2/src/tests/messaging_channel/mod.rs +10 -0
  74. package/contracts/endpoint-v2/src/tests/messaging_channel/next_guid.rs +239 -0
  75. package/contracts/endpoint-v2/src/tests/messaging_channel/nilify.rs +324 -0
  76. package/contracts/endpoint-v2/src/tests/messaging_channel/outbound_nonce.rs +242 -0
  77. package/contracts/endpoint-v2/src/tests/messaging_channel/skip.rs +232 -0
  78. package/contracts/endpoint-v2/src/tests/messaging_composer/clear_compose.rs +212 -0
  79. package/contracts/endpoint-v2/src/tests/messaging_composer/compose_queue.rs +213 -0
  80. package/contracts/endpoint-v2/src/tests/messaging_composer/lz_compose_alert.rs +269 -0
  81. package/contracts/endpoint-v2/src/tests/messaging_composer/mod.rs +4 -0
  82. package/contracts/endpoint-v2/src/tests/messaging_composer/send_compose.rs +173 -0
  83. package/contracts/endpoint-v2/src/tests/mock.rs +132 -0
  84. package/contracts/endpoint-v2/src/tests/mod.rs +12 -0
  85. package/contracts/endpoint-v2/src/tests/util/build_payload.rs +126 -0
  86. package/contracts/endpoint-v2/src/tests/util/compute_guid.rs +82 -0
  87. package/contracts/endpoint-v2/src/tests/util/keccak256.rs +115 -0
  88. package/contracts/endpoint-v2/src/tests/util/mod.rs +3 -0
  89. package/contracts/endpoint-v2/src/util.rs +52 -0
  90. package/contracts/message-libs/Cargo.toml +12 -0
  91. package/contracts/message-libs/block-message-lib/Cargo.toml +19 -0
  92. package/contracts/message-libs/block-message-lib/src/lib.rs +70 -0
  93. package/contracts/message-libs/lib.rs +2 -0
  94. package/contracts/message-libs/message-lib-common/Cargo.toml +24 -0
  95. package/contracts/message-libs/message-lib-common/src/errors.rs +20 -0
  96. package/contracts/message-libs/message-lib-common/src/interfaces/dvn.rs +55 -0
  97. package/contracts/message-libs/message-lib-common/src/interfaces/executor.rs +46 -0
  98. package/contracts/message-libs/message-lib-common/src/interfaces/mod.rs +7 -0
  99. package/contracts/message-libs/message-lib-common/src/interfaces/treasury.rs +17 -0
  100. package/contracts/message-libs/message-lib-common/src/lib.rs +14 -0
  101. package/contracts/message-libs/message-lib-common/src/packet_codec_v1.rs +99 -0
  102. package/contracts/message-libs/message-lib-common/src/testing_utils.rs +27 -0
  103. package/contracts/message-libs/message-lib-common/src/tests/mod.rs +2 -0
  104. package/contracts/message-libs/message-lib-common/src/tests/packet_codec_v1.rs +162 -0
  105. package/contracts/message-libs/message-lib-common/src/tests/worker_options.rs +319 -0
  106. package/contracts/message-libs/message-lib-common/src/worker_options.rs +190 -0
  107. package/contracts/message-libs/simple-message-lib/Cargo.toml +26 -0
  108. package/contracts/message-libs/simple-message-lib/src/errors.rs +11 -0
  109. package/contracts/message-libs/simple-message-lib/src/lib.rs +14 -0
  110. package/contracts/message-libs/simple-message-lib/src/simple_message_lib.rs +136 -0
  111. package/contracts/message-libs/simple-message-lib/src/storage.rs +27 -0
  112. package/contracts/message-libs/simple-message-lib/src/test.rs +280 -0
  113. package/contracts/message-libs/treasury/Cargo.toml +27 -0
  114. package/contracts/message-libs/treasury/src/errors.rs +10 -0
  115. package/contracts/message-libs/treasury/src/events.rs +28 -0
  116. package/contracts/message-libs/treasury/src/interfaces/mod.rs +3 -0
  117. package/contracts/message-libs/treasury/src/interfaces/zro_fee_lib.rs +20 -0
  118. package/contracts/message-libs/treasury/src/lib.rs +20 -0
  119. package/contracts/message-libs/treasury/src/storage.rs +18 -0
  120. package/contracts/message-libs/treasury/src/tests/mod.rs +2 -0
  121. package/contracts/message-libs/treasury/src/tests/setup.rs +112 -0
  122. package/contracts/message-libs/treasury/src/tests/treasury_tests.rs +562 -0
  123. package/contracts/message-libs/treasury/src/treasury.rs +140 -0
  124. package/contracts/message-libs/uln-302/Cargo.toml +28 -0
  125. package/contracts/message-libs/uln-302/src/config_validation.rs +173 -0
  126. package/contracts/message-libs/uln-302/src/errors.rs +29 -0
  127. package/contracts/message-libs/uln-302/src/events.rs +72 -0
  128. package/contracts/message-libs/uln-302/src/interfaces/mod.rs +5 -0
  129. package/contracts/message-libs/uln-302/src/interfaces/receive.rs +82 -0
  130. package/contracts/message-libs/uln-302/src/interfaces/send.rs +159 -0
  131. package/contracts/message-libs/uln-302/src/lib.rs +20 -0
  132. package/contracts/message-libs/uln-302/src/receive.rs +199 -0
  133. package/contracts/message-libs/uln-302/src/send.rs +349 -0
  134. package/contracts/message-libs/uln-302/src/storage.rs +47 -0
  135. package/contracts/message-libs/uln-302/src/tests/config/mod.rs +2 -0
  136. package/contracts/message-libs/uln-302/src/tests/config/oapp_uln_config.rs +291 -0
  137. package/contracts/message-libs/uln-302/src/tests/config/uln_config.rs +163 -0
  138. package/contracts/message-libs/uln-302/src/tests/mod.rs +7 -0
  139. package/contracts/message-libs/uln-302/src/tests/receive_uln302/commit_verification.rs +183 -0
  140. package/contracts/message-libs/uln-302/src/tests/receive_uln302/confirmations.rs +128 -0
  141. package/contracts/message-libs/uln-302/src/tests/receive_uln302/effective_receive_uln_config.rs +104 -0
  142. package/contracts/message-libs/uln-302/src/tests/receive_uln302/mod.rs +66 -0
  143. package/contracts/message-libs/uln-302/src/tests/receive_uln302/set_default_receive_uln_configs.rs +79 -0
  144. package/contracts/message-libs/uln-302/src/tests/receive_uln302/verifiable.rs +463 -0
  145. package/contracts/message-libs/uln-302/src/tests/receive_uln302/verify.rs +173 -0
  146. package/contracts/message-libs/uln-302/src/tests/send_uln302/effective_executor_config.rs +132 -0
  147. package/contracts/message-libs/uln-302/src/tests/send_uln302/effective_send_uln_config.rs +117 -0
  148. package/contracts/message-libs/uln-302/src/tests/send_uln302/mod.rs +6 -0
  149. package/contracts/message-libs/uln-302/src/tests/send_uln302/quote.rs +586 -0
  150. package/contracts/message-libs/uln-302/src/tests/send_uln302/send.rs +834 -0
  151. package/contracts/message-libs/uln-302/src/tests/send_uln302/set_default_executor_configs.rs +95 -0
  152. package/contracts/message-libs/uln-302/src/tests/send_uln302/set_default_send_uln_configs.rs +80 -0
  153. package/contracts/message-libs/uln-302/src/tests/setup.rs +268 -0
  154. package/contracts/message-libs/uln-302/src/tests/testing_utils.rs +47 -0
  155. package/contracts/message-libs/uln-302/src/tests/uln302/get_app_receive_uln_config.rs +51 -0
  156. package/contracts/message-libs/uln-302/src/tests/uln302/get_app_send_uln_config.rs +51 -0
  157. package/contracts/message-libs/uln-302/src/tests/uln302/get_oapp_executor_config.rs +48 -0
  158. package/contracts/message-libs/uln-302/src/tests/uln302/mod.rs +4 -0
  159. package/contracts/message-libs/uln-302/src/tests/uln302/set_config.rs +998 -0
  160. package/contracts/message-libs/uln-302/src/uln302.rs +117 -0
  161. package/contracts/oapp-macros/Cargo.toml +21 -0
  162. package/contracts/oapp-macros/src/lib.rs +408 -0
  163. package/contracts/oapp-macros/src/oapp_core.rs +49 -0
  164. package/contracts/oapp-macros/src/oapp_full.rs +15 -0
  165. package/contracts/oapp-macros/src/oapp_options_type3.rs +46 -0
  166. package/contracts/oapp-macros/src/oapp_receiver.rs +67 -0
  167. package/contracts/oapp-macros/src/oapp_sender.rs +23 -0
  168. package/contracts/oapp-macros/src/util.rs +103 -0
  169. package/contracts/oapp-macros/tests/test_macros.rs +522 -0
  170. package/contracts/oapps/Cargo.toml +12 -0
  171. package/contracts/oapps/counter/Cargo.toml +24 -0
  172. package/contracts/oapps/counter/integration_tests/mod.rs +3 -0
  173. package/contracts/oapps/counter/integration_tests/setup.rs +201 -0
  174. package/contracts/oapps/counter/integration_tests/test_with_sml.rs +166 -0
  175. package/contracts/oapps/counter/integration_tests/utils.rs +144 -0
  176. package/contracts/oapps/counter/src/codec.rs +63 -0
  177. package/contracts/oapps/counter/src/counter.rs +235 -0
  178. package/contracts/oapps/counter/src/errors.rs +9 -0
  179. package/contracts/oapps/counter/src/lib.rs +16 -0
  180. package/contracts/oapps/counter/src/options.rs +30 -0
  181. package/contracts/oapps/counter/src/storage.rs +33 -0
  182. package/contracts/oapps/counter/src/tests/mod.rs +37 -0
  183. package/contracts/oapps/counter/src/tests/test_codec.rs +64 -0
  184. package/contracts/oapps/counter/src/tests/test_counter.rs +390 -0
  185. package/contracts/oapps/counter/src/u256_ext.rs +21 -0
  186. package/contracts/oapps/lib.rs +2 -0
  187. package/contracts/oapps/oapp/Cargo.toml +21 -0
  188. package/contracts/oapps/oapp/src/errors.rs +9 -0
  189. package/contracts/oapps/oapp/src/lib.rs +10 -0
  190. package/contracts/oapps/oapp/src/oapp_core.rs +92 -0
  191. package/contracts/oapps/oapp/src/oapp_options_type3.rs +89 -0
  192. package/contracts/oapps/oapp/src/oapp_receiver.rs +72 -0
  193. package/contracts/oapps/oapp/src/oapp_sender.rs +66 -0
  194. package/contracts/oapps/oapp/src/tests/mod.rs +4 -0
  195. package/contracts/oapps/oapp/src/tests/test_oapp_core.rs +162 -0
  196. package/contracts/oapps/oapp/src/tests/test_oapp_options_type3.rs +180 -0
  197. package/contracts/oapps/oapp/src/tests/test_oapp_receiver.rs +157 -0
  198. package/contracts/oapps/oapp/src/tests/test_oapp_sender.rs +283 -0
  199. package/contracts/utils/Cargo.toml +21 -0
  200. package/contracts/utils/src/buffer_reader.rs +143 -0
  201. package/contracts/utils/src/buffer_writer.rs +117 -0
  202. package/contracts/utils/src/bytes_ext.rs +19 -0
  203. package/contracts/utils/src/errors.rs +30 -0
  204. package/contracts/utils/src/lib.rs +15 -0
  205. package/contracts/utils/src/option_ext.rs +38 -0
  206. package/contracts/utils/src/ownable.rs +88 -0
  207. package/contracts/utils/src/testing_utils.rs +100 -0
  208. package/contracts/utils/src/tests/buffer_reader.rs +1006 -0
  209. package/contracts/utils/src/tests/buffer_writer.rs +330 -0
  210. package/contracts/utils/src/tests/bytes_ext.rs +77 -0
  211. package/contracts/utils/src/tests/mod.rs +4 -0
  212. package/contracts/utils/src/tests/ownable.rs +149 -0
  213. package/contracts/utils/src/ttl.rs +164 -0
  214. package/contracts/workers/Cargo.toml +13 -0
  215. package/contracts/workers/executor/Cargo.toml +26 -0
  216. package/contracts/workers/executor/src/events.rs +22 -0
  217. package/contracts/workers/executor/src/executor.rs +347 -0
  218. package/contracts/workers/executor/src/interfaces/executor.rs +40 -0
  219. package/contracts/workers/executor/src/interfaces/mod.rs +5 -0
  220. package/contracts/workers/executor/src/interfaces/types.rs +51 -0
  221. package/contracts/workers/executor/src/lib.rs +10 -0
  222. package/contracts/workers/executor/src/storage.rs +23 -0
  223. package/contracts/workers/lib.rs +2 -0
  224. package/contracts/workers/worker-common/Cargo.toml +18 -0
  225. package/contracts/workers/worker-common/src/constants.rs +17 -0
  226. package/contracts/workers/worker-common/src/errors.rs +6 -0
  227. package/contracts/workers/worker-common/src/events.rs +34 -0
  228. package/contracts/workers/worker-common/src/interfaces/executor_fee_lib.rs +35 -0
  229. package/contracts/workers/worker-common/src/interfaces/mod.rs +7 -0
  230. package/contracts/workers/worker-common/src/interfaces/price_feed.rs +40 -0
  231. package/contracts/workers/worker-common/src/interfaces/worker.rs +60 -0
  232. package/contracts/workers/worker-common/src/lib.rs +19 -0
  233. package/contracts/workers/worker-common/src/storage.rs +32 -0
  234. package/contracts/workers/worker-common/src/worker_common.rs +166 -0
  235. package/package.json +25 -0
  236. package/rust-toolchain.toml +4 -0
  237. package/rustfmt.toml +17 -0
  238. package/sdk/.turbo/turbo-build.log +4 -0
  239. package/sdk/dist/generated/bml.d.ts +452 -0
  240. package/sdk/dist/generated/bml.js +72 -0
  241. package/sdk/dist/generated/counter.d.ts +824 -0
  242. package/sdk/dist/generated/counter.js +125 -0
  243. package/sdk/dist/generated/endpoint.d.ts +1676 -0
  244. package/sdk/dist/generated/endpoint.js +216 -0
  245. package/sdk/dist/generated/sml.d.ts +810 -0
  246. package/sdk/dist/generated/sml.js +132 -0
  247. package/sdk/dist/generated/uln302.d.ts +1227 -0
  248. package/sdk/dist/generated/uln302.js +185 -0
  249. package/sdk/dist/index.d.ts +5 -0
  250. package/sdk/dist/index.js +5 -0
  251. package/sdk/node_modules/.bin/tsc +21 -0
  252. package/sdk/node_modules/.bin/tsserver +21 -0
  253. package/sdk/node_modules/.bin/vitest +21 -0
  254. package/sdk/node_modules/.bin/zx +21 -0
  255. package/sdk/package.json +40 -0
  256. package/sdk/src/index.ts +5 -0
  257. package/sdk/test/index.test.ts +271 -0
  258. package/sdk/test/suites/constants.ts +13 -0
  259. package/sdk/test/suites/deploy.ts +277 -0
  260. package/sdk/test/suites/localnet.ts +42 -0
  261. package/sdk/test/suites/scan.ts +189 -0
  262. package/sdk/tsconfig.json +106 -0
  263. package/tools/ts-bindings-gen/Cargo.toml +14 -0
  264. package/tools/ts-bindings-gen/src/main.rs +147 -0
  265. package/turbo.json +12 -0
@@ -0,0 +1,998 @@
1
+ extern crate std;
2
+ use endpoint_v2::{MessageLibVersion, SetConfigParam};
3
+ use soroban_sdk::{testutils::Address as _, vec, xdr::ToXdr, Address};
4
+
5
+ use crate::{
6
+ config_validation::MAX_DVNS,
7
+ errors::Uln302Error,
8
+ interfaces::{ExecutorConfig, OAppUlnConfig, UlnConfig},
9
+ tests::setup::{setup, TestSetup},
10
+ uln302::{CONFIG_TYPE_RECEIVE_ULN, CONFIG_TYPE_SEND_ULN},
11
+ Uln302Client,
12
+ };
13
+
14
+ // ==================== Test Unsupported EID ====================
15
+
16
+ #[test]
17
+ fn test_set_config_unsupported_eid_should_fail() {
18
+ // Sui equivalent: test_set_config_unsupported_eid_should_fail
19
+ // Don't set up any configs for EID 999 - this makes it unsupported
20
+ let setup = setup();
21
+ let TestSetup { env, uln302, endpoint, .. } = setup;
22
+
23
+ let oapp = Address::generate(&env);
24
+ let unsupported_eid = 999u32;
25
+
26
+ // Create a valid OApp config
27
+ let config = OAppUlnConfig {
28
+ use_default_confirmations: true,
29
+ use_default_required_dvns: true,
30
+ use_default_optional_dvns: true,
31
+ uln_config: UlnConfig {
32
+ confirmations: 0,
33
+ required_dvns: vec![&env],
34
+ optional_dvns: vec![&env],
35
+ optional_dvn_threshold: 0,
36
+ },
37
+ };
38
+
39
+ let config_bytes = config.to_xdr(&env);
40
+ let params =
41
+ vec![&env, SetConfigParam { eid: unsupported_eid, config_type: CONFIG_TYPE_SEND_ULN, config: config_bytes }];
42
+
43
+ // This should fail with UnsupportedEid because EID 999 has no default configs
44
+ let result = endpoint.try_set_config(&Address::generate(&env), &oapp, &uln302.address, &params);
45
+ assert_eq!(result.err().unwrap().ok().unwrap(), Uln302Error::UnsupportedEid.into());
46
+ }
47
+
48
+ // ==================== Test Invalid Config Type ====================
49
+
50
+ #[test]
51
+ fn test_set_config_invalid_type_should_fail() {
52
+ // Sui equivalent: test_set_config_invalid_type_should_fail
53
+ let setup = setup();
54
+ let default_config = UlnConfig::generate(&setup.env, 15, 2, 3, 2);
55
+ let eid = 100;
56
+
57
+ // Set up configs for the EID to make it supported
58
+ setup.set_default_send_uln_config(eid, default_config.clone());
59
+ setup.set_default_receive_uln_config(eid, default_config.clone());
60
+
61
+ let TestSetup { env, uln302, endpoint, .. } = setup;
62
+ let oapp = Address::generate(&env);
63
+
64
+ // Create a valid OApp config
65
+ let config = OAppUlnConfig {
66
+ use_default_confirmations: true,
67
+ use_default_required_dvns: true,
68
+ use_default_optional_dvns: true,
69
+ uln_config: UlnConfig {
70
+ confirmations: 0,
71
+ required_dvns: vec![&env],
72
+ optional_dvns: vec![&env],
73
+ optional_dvn_threshold: 0,
74
+ },
75
+ };
76
+
77
+ let config_bytes = config.to_xdr(&env);
78
+ let invalid_config_type = 999u32; // Invalid config type (not 1, 2, or 3)
79
+ let params = vec![&env, SetConfigParam { eid, config_type: invalid_config_type, config: config_bytes }];
80
+
81
+ // This should fail with InvalidConfigType because config type 999 is invalid
82
+ let result = endpoint.try_set_config(&Address::generate(&env), &oapp, &uln302.address, &params);
83
+ assert_eq!(result.err().unwrap().ok().unwrap(), Uln302Error::InvalidConfigType.into());
84
+ }
85
+
86
+ // ==================== Test Invalid Confirmations ====================
87
+
88
+ #[test]
89
+ fn test_set_send_config_invalid_confirmations_use_default_but_nonzero() {
90
+ let setup = setup();
91
+ let default_config = UlnConfig::generate(&setup.env, 10, 2, 3, 2);
92
+ let eid = 100;
93
+
94
+ setup.set_default_send_uln_config(eid, default_config.clone());
95
+ setup.set_default_receive_uln_config(eid, default_config.clone());
96
+
97
+ let TestSetup { env, uln302, endpoint, .. } = setup;
98
+ let oapp = Address::generate(&env);
99
+
100
+ // Invalid: use_default_confirmations = true but confirmations != 0
101
+ let invalid_config = OAppUlnConfig {
102
+ use_default_confirmations: true,
103
+ use_default_required_dvns: true,
104
+ use_default_optional_dvns: true,
105
+ uln_config: UlnConfig {
106
+ confirmations: 99, // Should be 0 when using default
107
+ required_dvns: vec![&env],
108
+ optional_dvns: vec![&env],
109
+ optional_dvn_threshold: 0,
110
+ },
111
+ };
112
+
113
+ let config_bytes = invalid_config.to_xdr(&env);
114
+ let params = vec![&env, SetConfigParam { eid, config_type: CONFIG_TYPE_SEND_ULN, config: config_bytes }];
115
+ let result = endpoint.try_set_config(&Address::generate(&env), &oapp, &uln302.address, &params);
116
+ assert_eq!(result.err().unwrap().ok().unwrap(), Uln302Error::InvalidConfirmations.into());
117
+ }
118
+
119
+ #[test]
120
+ fn test_set_receive_config_invalid_confirmations_use_default_but_nonzero() {
121
+ let setup = setup();
122
+ let default_config = UlnConfig::generate(&setup.env, 15, 1, 2, 1);
123
+ let eid = 101;
124
+
125
+ setup.set_default_send_uln_config(eid, default_config.clone());
126
+ setup.set_default_receive_uln_config(eid, default_config.clone());
127
+
128
+ let TestSetup { env, uln302, endpoint, .. } = setup;
129
+ let oapp = Address::generate(&env);
130
+
131
+ // Invalid: use_default_confirmations = true but confirmations != 0
132
+ let invalid_config = OAppUlnConfig {
133
+ use_default_confirmations: true,
134
+ use_default_required_dvns: true,
135
+ use_default_optional_dvns: true,
136
+ uln_config: UlnConfig {
137
+ confirmations: 50, // Should be 0 when using default
138
+ required_dvns: vec![&env],
139
+ optional_dvns: vec![&env],
140
+ optional_dvn_threshold: 0,
141
+ },
142
+ };
143
+
144
+ let config_bytes = invalid_config.to_xdr(&env);
145
+ let params = vec![&env, SetConfigParam { eid, config_type: CONFIG_TYPE_RECEIVE_ULN, config: config_bytes }];
146
+ let result = endpoint.try_set_config(&Address::generate(&env), &oapp, &uln302.address, &params);
147
+ assert_eq!(result.err().unwrap().ok().unwrap(), Uln302Error::InvalidConfirmations.into());
148
+ }
149
+
150
+ #[test]
151
+ fn test_set_send_config_valid_confirmations_use_default_with_zero() {
152
+ let setup = setup();
153
+ let default_config = UlnConfig::generate(&setup.env, 10, 2, 3, 2);
154
+ let eid = 100;
155
+
156
+ setup.set_default_send_uln_config(eid, default_config.clone());
157
+ setup.set_default_receive_uln_config(eid, default_config.clone());
158
+
159
+ let TestSetup { env, uln302, endpoint, .. } = setup;
160
+ let oapp = Address::generate(&env);
161
+
162
+ // Valid: use_default_confirmations = true and confirmations == 0
163
+ let valid_config = OAppUlnConfig {
164
+ use_default_confirmations: true,
165
+ use_default_required_dvns: true,
166
+ use_default_optional_dvns: true,
167
+ uln_config: UlnConfig {
168
+ confirmations: 0, // Must be 0 when using default
169
+ required_dvns: vec![&env],
170
+ optional_dvns: vec![&env],
171
+ optional_dvn_threshold: 0,
172
+ },
173
+ };
174
+
175
+ let config_bytes = valid_config.to_xdr(&env);
176
+ let params = vec![&env, SetConfigParam { eid, config_type: CONFIG_TYPE_SEND_ULN, config: config_bytes }];
177
+ endpoint.set_config(&Address::generate(&env), &oapp, &uln302.address, &params);
178
+
179
+ // Should succeed
180
+ let result = uln302.oapp_send_uln_config(&oapp, &eid);
181
+ assert!(result.is_some());
182
+ }
183
+
184
+ #[test]
185
+ fn test_set_send_config_valid_confirmations_custom_with_any_value() {
186
+ let setup = setup();
187
+ let default_config = UlnConfig::generate(&setup.env, 10, 2, 3, 2);
188
+ let eid = 100;
189
+
190
+ setup.set_default_send_uln_config(eid, default_config.clone());
191
+ setup.set_default_receive_uln_config(eid, default_config.clone());
192
+
193
+ let TestSetup { env, uln302, endpoint, .. } = setup;
194
+ let oapp = Address::generate(&env);
195
+
196
+ // Valid: use_default_confirmations = false, confirmations can be any value
197
+ let valid_config = OAppUlnConfig {
198
+ use_default_confirmations: false,
199
+ use_default_required_dvns: true,
200
+ use_default_optional_dvns: true,
201
+ uln_config: UlnConfig {
202
+ confirmations: 25, // Can be any value when not using default
203
+ required_dvns: vec![&env],
204
+ optional_dvns: vec![&env],
205
+ optional_dvn_threshold: 0,
206
+ },
207
+ };
208
+
209
+ let config_bytes = valid_config.to_xdr(&env);
210
+ let params = vec![&env, SetConfigParam { eid, config_type: CONFIG_TYPE_SEND_ULN, config: config_bytes }];
211
+ endpoint.set_config(&Address::generate(&env), &oapp, &uln302.address, &params);
212
+
213
+ // Should succeed
214
+ let result = uln302.oapp_send_uln_config(&oapp, &eid);
215
+ assert!(result.is_some());
216
+ }
217
+
218
+ // ==================== Test Invalid Required DVNs ====================
219
+
220
+ #[test]
221
+ fn test_set_send_config_invalid_required_dvns_use_default_but_not_empty() {
222
+ let setup = setup();
223
+ let default_config = UlnConfig::generate(&setup.env, 10, 2, 3, 2);
224
+ let eid = 100;
225
+
226
+ setup.set_default_send_uln_config(eid, default_config.clone());
227
+ setup.set_default_receive_uln_config(eid, default_config.clone());
228
+
229
+ let TestSetup { env, uln302, endpoint, .. } = setup;
230
+ let oapp = Address::generate(&env);
231
+
232
+ // Invalid: use_default_required_dvns = true but required_dvns is not empty
233
+ let invalid_config = OAppUlnConfig {
234
+ use_default_confirmations: true,
235
+ use_default_required_dvns: true,
236
+ use_default_optional_dvns: true,
237
+ uln_config: UlnConfig {
238
+ confirmations: 0, // Must be 0 when using default
239
+ required_dvns: vec![&env, Address::generate(&env)], // Should be empty when using default
240
+ optional_dvns: vec![&env],
241
+ optional_dvn_threshold: 0,
242
+ },
243
+ };
244
+
245
+ let config_bytes = invalid_config.to_xdr(&env);
246
+ let params = vec![&env, SetConfigParam { eid, config_type: CONFIG_TYPE_SEND_ULN, config: config_bytes }];
247
+ let result = endpoint.try_set_config(&Address::generate(&env), &oapp, &uln302.address, &params);
248
+ assert_eq!(result.err().unwrap().ok().unwrap(), Uln302Error::InvalidRequiredDVNs.into());
249
+ }
250
+
251
+ #[test]
252
+ fn test_set_receive_config_invalid_required_dvns_use_default_but_not_empty() {
253
+ let setup = setup();
254
+ let default_config = UlnConfig::generate(&setup.env, 15, 1, 2, 1);
255
+ let eid = 101;
256
+
257
+ setup.set_default_send_uln_config(eid, default_config.clone());
258
+ setup.set_default_receive_uln_config(eid, default_config.clone());
259
+
260
+ let TestSetup { env, uln302, endpoint, .. } = setup;
261
+ let oapp = Address::generate(&env);
262
+
263
+ // Invalid: use_default_required_dvns = true but required_dvns is not empty
264
+ let invalid_config = OAppUlnConfig {
265
+ use_default_confirmations: true,
266
+ use_default_required_dvns: true,
267
+ use_default_optional_dvns: true,
268
+ uln_config: UlnConfig {
269
+ confirmations: 0, // Must be 0 when using default
270
+ required_dvns: vec![&env, Address::generate(&env), Address::generate(&env)], // Should be empty
271
+ optional_dvns: vec![&env],
272
+ optional_dvn_threshold: 0,
273
+ },
274
+ };
275
+
276
+ let config_bytes = invalid_config.to_xdr(&env);
277
+ let params = vec![&env, SetConfigParam { eid, config_type: CONFIG_TYPE_RECEIVE_ULN, config: config_bytes }];
278
+ let result = endpoint.try_set_config(&Address::generate(&env), &oapp, &uln302.address, &params);
279
+ assert_eq!(result.err().unwrap().ok().unwrap(), Uln302Error::InvalidRequiredDVNs.into());
280
+ }
281
+
282
+ #[test]
283
+ fn test_set_send_config_valid_required_dvns_use_default_with_empty() {
284
+ let setup = setup();
285
+ let default_config = UlnConfig::generate(&setup.env, 10, 2, 3, 2);
286
+ let eid = 100;
287
+
288
+ setup.set_default_send_uln_config(eid, default_config.clone());
289
+ setup.set_default_receive_uln_config(eid, default_config.clone());
290
+
291
+ let TestSetup { env, uln302, endpoint, .. } = setup;
292
+ let oapp = Address::generate(&env);
293
+
294
+ // Valid: use_default_required_dvns = true and required_dvns is empty
295
+ let valid_config = OAppUlnConfig {
296
+ use_default_confirmations: true,
297
+ use_default_required_dvns: true,
298
+ use_default_optional_dvns: true,
299
+ uln_config: UlnConfig {
300
+ confirmations: 0, // Must be 0 when using default
301
+ required_dvns: vec![&env], // Empty when using default
302
+ optional_dvns: vec![&env],
303
+ optional_dvn_threshold: 0,
304
+ },
305
+ };
306
+
307
+ let config_bytes = valid_config.to_xdr(&env);
308
+ let params = vec![&env, SetConfigParam { eid, config_type: CONFIG_TYPE_SEND_ULN, config: config_bytes }];
309
+ endpoint.set_config(&Address::generate(&env), &oapp, &uln302.address, &params);
310
+
311
+ // Should succeed
312
+ let result = uln302.oapp_send_uln_config(&oapp, &eid);
313
+ assert!(result.is_some());
314
+ }
315
+
316
+ #[test]
317
+ fn test_set_send_config_invalid_required_dvns_duplicates() {
318
+ let setup = setup();
319
+ let default_config = UlnConfig::generate(&setup.env, 10, 2, 3, 2);
320
+ let eid = 100;
321
+
322
+ setup.set_default_send_uln_config(eid, default_config.clone());
323
+ setup.set_default_receive_uln_config(eid, default_config.clone());
324
+
325
+ let TestSetup { env, uln302, endpoint, .. } = setup;
326
+ let oapp = Address::generate(&env);
327
+
328
+ let dvn1 = Address::generate(&env);
329
+
330
+ // Invalid: duplicate required DVNs
331
+ let invalid_config = OAppUlnConfig {
332
+ use_default_confirmations: false,
333
+ use_default_required_dvns: false,
334
+ use_default_optional_dvns: true,
335
+ uln_config: UlnConfig {
336
+ confirmations: 20,
337
+ required_dvns: vec![&env, dvn1.clone(), dvn1.clone()], // Duplicate
338
+ optional_dvns: vec![&env],
339
+ optional_dvn_threshold: 0,
340
+ },
341
+ };
342
+
343
+ let config_bytes = invalid_config.to_xdr(&env);
344
+ let params = vec![&env, SetConfigParam { eid, config_type: CONFIG_TYPE_SEND_ULN, config: config_bytes }];
345
+ let result = endpoint.try_set_config(&Address::generate(&env), &oapp, &uln302.address, &params);
346
+ assert_eq!(result.err().unwrap().ok().unwrap(), Uln302Error::DuplicateRequiredDVNs.into());
347
+ }
348
+
349
+ #[test]
350
+ fn test_set_send_config_invalid_required_dvns_too_many() {
351
+ let setup = setup();
352
+ let default_config = UlnConfig::generate(&setup.env, 10, 2, 3, 2);
353
+ let eid = 100;
354
+
355
+ setup.set_default_send_uln_config(eid, default_config.clone());
356
+ setup.set_default_receive_uln_config(eid, default_config.clone());
357
+
358
+ let TestSetup { env, uln302, endpoint, .. } = setup;
359
+ let oapp = Address::generate(&env);
360
+
361
+ // Create too many DVNs (MAX_DVNS + 1)
362
+ let mut required_dvns = vec![&env];
363
+ for _ in 0..(MAX_DVNS + 1) {
364
+ required_dvns.push_back(Address::generate(&env));
365
+ }
366
+
367
+ // Invalid: too many required DVNs
368
+ let invalid_config = OAppUlnConfig {
369
+ use_default_confirmations: false,
370
+ use_default_required_dvns: false,
371
+ use_default_optional_dvns: true,
372
+ uln_config: UlnConfig {
373
+ confirmations: 20,
374
+ required_dvns,
375
+ optional_dvns: vec![&env],
376
+ optional_dvn_threshold: 0,
377
+ },
378
+ };
379
+
380
+ let config_bytes = invalid_config.to_xdr(&env);
381
+ let params = vec![&env, SetConfigParam { eid, config_type: CONFIG_TYPE_SEND_ULN, config: config_bytes }];
382
+ let result = endpoint.try_set_config(&Address::generate(&env), &oapp, &uln302.address, &params);
383
+ assert_eq!(result.err().unwrap().ok().unwrap(), Uln302Error::InvalidRequiredDVNCount.into());
384
+ }
385
+
386
+ #[test]
387
+ fn test_set_send_config_valid_required_dvns_custom() {
388
+ let setup = setup();
389
+ let default_config = UlnConfig::generate(&setup.env, 10, 2, 3, 2);
390
+ let eid = 100;
391
+
392
+ setup.set_default_send_uln_config(eid, default_config.clone());
393
+ setup.set_default_receive_uln_config(eid, default_config.clone());
394
+
395
+ let TestSetup { env, uln302, endpoint, .. } = setup;
396
+ let oapp = Address::generate(&env);
397
+
398
+ // Valid: custom required DVNs without duplicates and within limit
399
+ let valid_config = OAppUlnConfig {
400
+ use_default_confirmations: false,
401
+ use_default_required_dvns: false,
402
+ use_default_optional_dvns: true,
403
+ uln_config: UlnConfig {
404
+ confirmations: 20,
405
+ required_dvns: vec![&env, Address::generate(&env), Address::generate(&env)],
406
+ optional_dvns: vec![&env],
407
+ optional_dvn_threshold: 0,
408
+ },
409
+ };
410
+
411
+ let config_bytes = valid_config.to_xdr(&env);
412
+ let params = vec![&env, SetConfigParam { eid, config_type: CONFIG_TYPE_SEND_ULN, config: config_bytes }];
413
+ endpoint.set_config(&Address::generate(&env), &oapp, &uln302.address, &params);
414
+
415
+ // Should succeed
416
+ let result = uln302.oapp_send_uln_config(&oapp, &eid);
417
+ assert!(result.is_some());
418
+ }
419
+
420
+ // ==================== Test Invalid Optional DVNs ====================
421
+
422
+ #[test]
423
+ fn test_set_send_config_invalid_optional_dvns_use_default_but_threshold_nonzero() {
424
+ let setup = setup();
425
+ let default_config = UlnConfig::generate(&setup.env, 10, 2, 3, 2);
426
+ let eid = 100;
427
+
428
+ setup.set_default_send_uln_config(eid, default_config.clone());
429
+ setup.set_default_receive_uln_config(eid, default_config.clone());
430
+
431
+ let TestSetup { env, uln302, endpoint, .. } = setup;
432
+ let oapp = Address::generate(&env);
433
+
434
+ // Invalid: use_default_optional_dvns = true but threshold != 0
435
+ let invalid_config = OAppUlnConfig {
436
+ use_default_confirmations: true,
437
+ use_default_required_dvns: true,
438
+ use_default_optional_dvns: true,
439
+ uln_config: UlnConfig {
440
+ confirmations: 0, // Must be 0 when using default
441
+ required_dvns: vec![&env],
442
+ optional_dvns: vec![&env],
443
+ optional_dvn_threshold: 1, // Should be 0 when using default
444
+ },
445
+ };
446
+
447
+ let config_bytes = invalid_config.to_xdr(&env);
448
+ let params = vec![&env, SetConfigParam { eid, config_type: CONFIG_TYPE_SEND_ULN, config: config_bytes }];
449
+ let result = endpoint.try_set_config(&Address::generate(&env), &oapp, &uln302.address, &params);
450
+ assert_eq!(result.err().unwrap().ok().unwrap(), Uln302Error::InvalidOptionalDVNs.into());
451
+ }
452
+
453
+ #[test]
454
+ fn test_set_send_config_invalid_optional_dvns_use_default_but_dvns_not_empty() {
455
+ let setup = setup();
456
+ let default_config = UlnConfig::generate(&setup.env, 10, 2, 3, 2);
457
+ let eid = 100;
458
+
459
+ setup.set_default_send_uln_config(eid, default_config.clone());
460
+ setup.set_default_receive_uln_config(eid, default_config.clone());
461
+
462
+ let TestSetup { env, uln302, endpoint, .. } = setup;
463
+ let oapp = Address::generate(&env);
464
+
465
+ // Invalid: use_default_optional_dvns = true but optional_dvns is not empty
466
+ let invalid_config = OAppUlnConfig {
467
+ use_default_confirmations: true,
468
+ use_default_required_dvns: true,
469
+ use_default_optional_dvns: true,
470
+ uln_config: UlnConfig {
471
+ confirmations: 0, // Must be 0 when using default
472
+ required_dvns: vec![&env],
473
+ optional_dvns: vec![&env, Address::generate(&env)], // Should be empty when using default
474
+ optional_dvn_threshold: 0,
475
+ },
476
+ };
477
+
478
+ let config_bytes = invalid_config.to_xdr(&env);
479
+ let params = vec![&env, SetConfigParam { eid, config_type: CONFIG_TYPE_SEND_ULN, config: config_bytes }];
480
+ let result = endpoint.try_set_config(&Address::generate(&env), &oapp, &uln302.address, &params);
481
+ assert_eq!(result.err().unwrap().ok().unwrap(), Uln302Error::InvalidOptionalDVNs.into());
482
+ }
483
+
484
+ #[test]
485
+ fn test_set_receive_config_invalid_optional_dvns_use_default_but_threshold_nonzero() {
486
+ let setup = setup();
487
+ let default_config = UlnConfig::generate(&setup.env, 15, 1, 2, 1);
488
+ let eid = 101;
489
+
490
+ setup.set_default_send_uln_config(eid, default_config.clone());
491
+ setup.set_default_receive_uln_config(eid, default_config.clone());
492
+
493
+ let TestSetup { env, uln302, endpoint, .. } = setup;
494
+ let oapp = Address::generate(&env);
495
+
496
+ // Invalid: use_default_optional_dvns = true but threshold != 0
497
+ let invalid_config = OAppUlnConfig {
498
+ use_default_confirmations: true,
499
+ use_default_required_dvns: true,
500
+ use_default_optional_dvns: true,
501
+ uln_config: UlnConfig {
502
+ confirmations: 0, // Must be 0 when using default
503
+ required_dvns: vec![&env],
504
+ optional_dvns: vec![&env],
505
+ optional_dvn_threshold: 2, // Should be 0 when using default
506
+ },
507
+ };
508
+
509
+ let config_bytes = invalid_config.to_xdr(&env);
510
+ let params = vec![&env, SetConfigParam { eid, config_type: CONFIG_TYPE_RECEIVE_ULN, config: config_bytes }];
511
+ let result = endpoint.try_set_config(&Address::generate(&env), &oapp, &uln302.address, &params);
512
+ assert_eq!(result.err().unwrap().ok().unwrap(), Uln302Error::InvalidOptionalDVNs.into());
513
+ }
514
+
515
+ #[test]
516
+ fn test_set_send_config_valid_optional_dvns_use_default() {
517
+ let setup = setup();
518
+ let default_config = UlnConfig::generate(&setup.env, 10, 2, 3, 2);
519
+ let eid = 100;
520
+
521
+ setup.set_default_send_uln_config(eid, default_config.clone());
522
+ setup.set_default_receive_uln_config(eid, default_config.clone());
523
+
524
+ let TestSetup { env, uln302, endpoint, .. } = setup;
525
+ let oapp = Address::generate(&env);
526
+
527
+ // Valid: use_default_optional_dvns = true with threshold = 0 and empty dvns
528
+ let valid_config = OAppUlnConfig {
529
+ use_default_confirmations: true,
530
+ use_default_required_dvns: true,
531
+ use_default_optional_dvns: true,
532
+ uln_config: UlnConfig {
533
+ confirmations: 0, // Must be 0 when using default
534
+ required_dvns: vec![&env],
535
+ optional_dvns: vec![&env],
536
+ optional_dvn_threshold: 0,
537
+ },
538
+ };
539
+
540
+ let config_bytes = valid_config.to_xdr(&env);
541
+ let params = vec![&env, SetConfigParam { eid, config_type: CONFIG_TYPE_SEND_ULN, config: config_bytes }];
542
+ endpoint.set_config(&Address::generate(&env), &oapp, &uln302.address, &params);
543
+
544
+ // Should succeed
545
+ let result = uln302.oapp_send_uln_config(&oapp, &eid);
546
+ assert!(result.is_some());
547
+ }
548
+
549
+ #[test]
550
+ fn test_set_send_config_invalid_optional_dvns_duplicates() {
551
+ let setup = setup();
552
+ let default_config = UlnConfig::generate(&setup.env, 10, 2, 3, 2);
553
+ let eid = 100;
554
+
555
+ setup.set_default_send_uln_config(eid, default_config.clone());
556
+ setup.set_default_receive_uln_config(eid, default_config.clone());
557
+
558
+ let TestSetup { env, uln302, endpoint, .. } = setup;
559
+ let oapp = Address::generate(&env);
560
+
561
+ let dvn1 = Address::generate(&env);
562
+
563
+ // Invalid: duplicate optional DVNs
564
+ let invalid_config = OAppUlnConfig {
565
+ use_default_confirmations: false,
566
+ use_default_required_dvns: false,
567
+ use_default_optional_dvns: false,
568
+ uln_config: UlnConfig {
569
+ confirmations: 20,
570
+ required_dvns: vec![&env, Address::generate(&env)],
571
+ optional_dvns: vec![&env, dvn1.clone(), dvn1.clone()], // Duplicate
572
+ optional_dvn_threshold: 1,
573
+ },
574
+ };
575
+
576
+ let config_bytes = invalid_config.to_xdr(&env);
577
+ let params = vec![&env, SetConfigParam { eid, config_type: CONFIG_TYPE_SEND_ULN, config: config_bytes }];
578
+ let result = endpoint.try_set_config(&Address::generate(&env), &oapp, &uln302.address, &params);
579
+ assert_eq!(result.err().unwrap().ok().unwrap(), Uln302Error::DuplicateOptionalDVNs.into());
580
+ }
581
+
582
+ #[test]
583
+ fn test_set_send_config_invalid_optional_dvns_too_many() {
584
+ let setup = setup();
585
+ let default_config = UlnConfig::generate(&setup.env, 10, 2, 3, 2);
586
+ let eid = 100;
587
+
588
+ setup.set_default_send_uln_config(eid, default_config.clone());
589
+ setup.set_default_receive_uln_config(eid, default_config.clone());
590
+
591
+ let TestSetup { env, uln302, endpoint, .. } = setup;
592
+ let oapp = Address::generate(&env);
593
+
594
+ // Create too many DVNs (MAX_DVNS + 1)
595
+ let mut optional_dvns = vec![&env];
596
+ for _ in 0..(MAX_DVNS + 1) {
597
+ optional_dvns.push_back(Address::generate(&env));
598
+ }
599
+
600
+ // Invalid: too many optional DVNs
601
+ let invalid_config = OAppUlnConfig {
602
+ use_default_confirmations: false,
603
+ use_default_required_dvns: false,
604
+ use_default_optional_dvns: false,
605
+ uln_config: UlnConfig {
606
+ confirmations: 20,
607
+ required_dvns: vec![&env, Address::generate(&env)],
608
+ optional_dvns,
609
+ optional_dvn_threshold: 1,
610
+ },
611
+ };
612
+
613
+ let config_bytes = invalid_config.to_xdr(&env);
614
+ let params = vec![&env, SetConfigParam { eid, config_type: CONFIG_TYPE_SEND_ULN, config: config_bytes }];
615
+ let result = endpoint.try_set_config(&Address::generate(&env), &oapp, &uln302.address, &params);
616
+ assert_eq!(result.err().unwrap().ok().unwrap(), Uln302Error::InvalidOptionalDVNCount.into());
617
+ }
618
+
619
+ #[test]
620
+ fn test_set_send_config_invalid_optional_dvns_threshold_zero_with_dvns() {
621
+ let setup = setup();
622
+ let default_config = UlnConfig::generate(&setup.env, 10, 2, 3, 2);
623
+ let eid = 100;
624
+
625
+ setup.set_default_send_uln_config(eid, default_config.clone());
626
+ setup.set_default_receive_uln_config(eid, default_config.clone());
627
+
628
+ let TestSetup { env, uln302, endpoint, .. } = setup;
629
+ let oapp = Address::generate(&env);
630
+
631
+ // Invalid: threshold = 0 but optional_dvns is not empty
632
+ let invalid_config = OAppUlnConfig {
633
+ use_default_confirmations: false,
634
+ use_default_required_dvns: false,
635
+ use_default_optional_dvns: false,
636
+ uln_config: UlnConfig {
637
+ confirmations: 20,
638
+ required_dvns: vec![&env, Address::generate(&env)],
639
+ optional_dvns: vec![&env, Address::generate(&env)],
640
+ optional_dvn_threshold: 0, // Should be > 0 if optional_dvns is not empty
641
+ },
642
+ };
643
+
644
+ let config_bytes = invalid_config.to_xdr(&env);
645
+ let params = vec![&env, SetConfigParam { eid, config_type: CONFIG_TYPE_SEND_ULN, config: config_bytes }];
646
+ let result = endpoint.try_set_config(&Address::generate(&env), &oapp, &uln302.address, &params);
647
+ assert_eq!(result.err().unwrap().ok().unwrap(), Uln302Error::InvalidOptionalDVNThreshold.into());
648
+ }
649
+
650
+ #[test]
651
+ fn test_set_send_config_invalid_optional_dvns_threshold_greater_than_dvns() {
652
+ let setup = setup();
653
+ let default_config = UlnConfig::generate(&setup.env, 10, 2, 3, 2);
654
+ let eid = 100;
655
+
656
+ setup.set_default_send_uln_config(eid, default_config.clone());
657
+ setup.set_default_receive_uln_config(eid, default_config.clone());
658
+
659
+ let TestSetup { env, uln302, endpoint, .. } = setup;
660
+ let oapp = Address::generate(&env);
661
+
662
+ // Invalid: threshold > optional_dvns.len()
663
+ let invalid_config = OAppUlnConfig {
664
+ use_default_confirmations: false,
665
+ use_default_required_dvns: false,
666
+ use_default_optional_dvns: false,
667
+ uln_config: UlnConfig {
668
+ confirmations: 20,
669
+ required_dvns: vec![&env, Address::generate(&env)],
670
+ optional_dvns: vec![&env, Address::generate(&env), Address::generate(&env)],
671
+ optional_dvn_threshold: 3, // Greater than 2 DVNs
672
+ },
673
+ };
674
+
675
+ let config_bytes = invalid_config.to_xdr(&env);
676
+ let params = vec![&env, SetConfigParam { eid, config_type: CONFIG_TYPE_SEND_ULN, config: config_bytes }];
677
+ let result = endpoint.try_set_config(&Address::generate(&env), &oapp, &uln302.address, &params);
678
+ assert_eq!(result.err().unwrap().ok().unwrap(), Uln302Error::InvalidOptionalDVNThreshold.into());
679
+ }
680
+
681
+ #[test]
682
+ fn test_set_send_config_valid_optional_dvns_custom() {
683
+ let setup = setup();
684
+ let default_config = UlnConfig::generate(&setup.env, 10, 2, 3, 2);
685
+ let eid = 100;
686
+
687
+ setup.set_default_send_uln_config(eid, default_config.clone());
688
+ setup.set_default_receive_uln_config(eid, default_config.clone());
689
+
690
+ let TestSetup { env, uln302, endpoint, .. } = setup;
691
+ let oapp = Address::generate(&env);
692
+
693
+ // Valid: custom optional DVNs with valid threshold
694
+ let valid_config = OAppUlnConfig {
695
+ use_default_confirmations: false,
696
+ use_default_required_dvns: false,
697
+ use_default_optional_dvns: false,
698
+ uln_config: UlnConfig {
699
+ confirmations: 20,
700
+ required_dvns: vec![&env, Address::generate(&env)],
701
+ optional_dvns: vec![&env, Address::generate(&env), Address::generate(&env), Address::generate(&env)],
702
+ optional_dvn_threshold: 2,
703
+ },
704
+ };
705
+
706
+ let config_bytes = valid_config.to_xdr(&env);
707
+ let params = vec![&env, SetConfigParam { eid, config_type: CONFIG_TYPE_SEND_ULN, config: config_bytes }];
708
+ endpoint.set_config(&Address::generate(&env), &oapp, &uln302.address, &params);
709
+
710
+ // Should succeed
711
+ let result = uln302.oapp_send_uln_config(&oapp, &eid);
712
+ assert!(result.is_some());
713
+ }
714
+
715
+ #[test]
716
+ fn test_set_send_config_valid_optional_dvns_custom_empty() {
717
+ let setup = setup();
718
+ let default_config = UlnConfig::generate(&setup.env, 10, 2, 3, 2);
719
+ let eid = 100;
720
+
721
+ setup.set_default_send_uln_config(eid, default_config.clone());
722
+ setup.set_default_receive_uln_config(eid, default_config.clone());
723
+
724
+ let TestSetup { env, uln302, endpoint, .. } = setup;
725
+ let oapp = Address::generate(&env);
726
+
727
+ // Valid: threshold = 0 with empty optional_dvns
728
+ let valid_config = OAppUlnConfig {
729
+ use_default_confirmations: false,
730
+ use_default_required_dvns: false,
731
+ use_default_optional_dvns: false,
732
+ uln_config: UlnConfig {
733
+ confirmations: 20,
734
+ required_dvns: vec![&env, Address::generate(&env)],
735
+ optional_dvns: vec![&env],
736
+ optional_dvn_threshold: 0,
737
+ },
738
+ };
739
+
740
+ let config_bytes = valid_config.to_xdr(&env);
741
+ let params = vec![&env, SetConfigParam { eid, config_type: CONFIG_TYPE_SEND_ULN, config: config_bytes }];
742
+ endpoint.set_config(&Address::generate(&env), &oapp, &uln302.address, &params);
743
+
744
+ // Should succeed
745
+ let result = uln302.oapp_send_uln_config(&oapp, &eid);
746
+ assert!(result.is_some());
747
+ }
748
+
749
+ // ==================== Test Combined Scenarios ====================
750
+
751
+ #[test]
752
+ fn test_set_send_config_valid_all_custom() {
753
+ let setup = setup();
754
+ let default_config = UlnConfig::generate(&setup.env, 10, 2, 3, 2);
755
+ let eid = 100;
756
+
757
+ setup.set_default_send_uln_config(eid, default_config.clone());
758
+ setup.set_default_receive_uln_config(eid, default_config.clone());
759
+
760
+ let TestSetup { env, uln302, endpoint, .. } = setup;
761
+ let oapp = Address::generate(&env);
762
+
763
+ // Valid: all custom values
764
+ let valid_config = OAppUlnConfig {
765
+ use_default_confirmations: false,
766
+ use_default_required_dvns: false,
767
+ use_default_optional_dvns: false,
768
+ uln_config: UlnConfig {
769
+ confirmations: 50,
770
+ required_dvns: vec![&env, Address::generate(&env), Address::generate(&env)],
771
+ optional_dvns: vec![&env, Address::generate(&env)],
772
+ optional_dvn_threshold: 1,
773
+ },
774
+ };
775
+
776
+ let config_bytes = valid_config.to_xdr(&env);
777
+ let params = vec![&env, SetConfigParam { eid, config_type: CONFIG_TYPE_SEND_ULN, config: config_bytes }];
778
+ endpoint.set_config(&Address::generate(&env), &oapp, &uln302.address, &params);
779
+
780
+ // Should succeed
781
+ let result = uln302.oapp_send_uln_config(&oapp, &eid);
782
+ assert!(result.is_some());
783
+ }
784
+
785
+ #[test]
786
+ fn test_set_receive_config_valid_all_custom() {
787
+ let setup = setup();
788
+ let default_config = UlnConfig::generate(&setup.env, 15, 1, 2, 1);
789
+ let eid = 101;
790
+
791
+ setup.set_default_send_uln_config(eid, default_config.clone());
792
+ setup.set_default_receive_uln_config(eid, default_config.clone());
793
+
794
+ let TestSetup { env, uln302, endpoint, .. } = setup;
795
+ let oapp = Address::generate(&env);
796
+
797
+ // Valid: all custom values
798
+ let valid_config = OAppUlnConfig {
799
+ use_default_confirmations: false,
800
+ use_default_required_dvns: false,
801
+ use_default_optional_dvns: false,
802
+ uln_config: UlnConfig {
803
+ confirmations: 30,
804
+ required_dvns: vec![&env, Address::generate(&env)],
805
+ optional_dvns: vec![&env, Address::generate(&env), Address::generate(&env)],
806
+ optional_dvn_threshold: 2,
807
+ },
808
+ };
809
+
810
+ let config_bytes = valid_config.to_xdr(&env);
811
+ let params = vec![&env, SetConfigParam { eid, config_type: CONFIG_TYPE_RECEIVE_ULN, config: config_bytes }];
812
+ endpoint.set_config(&Address::generate(&env), &oapp, &uln302.address, &params);
813
+
814
+ // Should succeed
815
+ let result = uln302.oapp_receive_uln_config(&oapp, &eid);
816
+ assert!(result.is_some());
817
+ }
818
+
819
+ #[test]
820
+ fn test_set_send_config_invalid_multiple_errors_confirmations_first() {
821
+ let setup = setup();
822
+ let default_config = UlnConfig::generate(&setup.env, 10, 2, 3, 2);
823
+ let eid = 100;
824
+
825
+ setup.set_default_send_uln_config(eid, default_config.clone());
826
+ setup.set_default_receive_uln_config(eid, default_config.clone());
827
+
828
+ let TestSetup { env, uln302, endpoint, .. } = setup;
829
+ let oapp = Address::generate(&env);
830
+
831
+ // Multiple errors: invalid confirmations and invalid required_dvns
832
+ // Should fail on confirmations check first
833
+ let invalid_config = OAppUlnConfig {
834
+ use_default_confirmations: true,
835
+ use_default_required_dvns: true,
836
+ use_default_optional_dvns: true,
837
+ uln_config: UlnConfig {
838
+ confirmations: 99, // Invalid - should be 0 when using default
839
+ required_dvns: vec![&env, Address::generate(&env)], // Also invalid - should be empty when using default
840
+ optional_dvns: vec![&env],
841
+ optional_dvn_threshold: 0,
842
+ },
843
+ };
844
+
845
+ let config_bytes = invalid_config.to_xdr(&env);
846
+ let params = vec![&env, SetConfigParam { eid, config_type: CONFIG_TYPE_SEND_ULN, config: config_bytes }];
847
+ let result = endpoint.try_set_config(&Address::generate(&env), &oapp, &uln302.address, &params);
848
+ assert_eq!(result.err().unwrap().ok().unwrap(), Uln302Error::InvalidConfirmations.into());
849
+ }
850
+
851
+ // ==================== Version Tests ====================
852
+
853
+ #[test]
854
+ fn test_version() {
855
+ // Sui equivalent: test_uln302_initialization / test_version_and_utility
856
+ // Tests that ULN-302 version returns (3, 0, 2)
857
+ let TestSetup { env, uln302, .. } = setup();
858
+
859
+ let uln302_client = Uln302Client::new(&env, &uln302.address);
860
+ let version = uln302_client.version();
861
+
862
+ assert_eq!(version.major, 3);
863
+ assert_eq!(version.minor, 0);
864
+ assert_eq!(version.endpoint_version, 2);
865
+ assert_eq!(version, MessageLibVersion { major: 3, minor: 0, endpoint_version: 2 });
866
+ }
867
+
868
+ // ==================== Supported EID Tests ====================
869
+
870
+ #[test]
871
+ fn test_is_supported_eid_initially_false() {
872
+ // Sui equivalent: test_version_and_utility (is_supported_eid before configs)
873
+ // Tests that is_supported_eid returns false initially
874
+ let TestSetup { env, uln302, .. } = setup();
875
+
876
+ let uln302_client = Uln302Client::new(&env, &uln302.address);
877
+
878
+ // No configs set - should not be supported
879
+ let eid = 999u32;
880
+ assert!(!uln302_client.is_supported_eid(&eid));
881
+ }
882
+
883
+ #[test]
884
+ fn test_is_supported_eid_true_after_configs() {
885
+ // Sui equivalent: test_version_and_utility (is_supported_eid after configs)
886
+ // Tests that is_supported_eid returns true after both send and receive configs are set
887
+ let setup = setup();
888
+ let eid = 100u32;
889
+
890
+ // Set both send and receive configs
891
+ let config = UlnConfig::generate(&setup.env, 15, 2, 3, 2);
892
+ setup.set_default_send_uln_config(eid, config.clone());
893
+ setup.set_default_receive_uln_config(eid, config);
894
+
895
+ let TestSetup { env, uln302, .. } = setup;
896
+ let uln302_client = Uln302Client::new(&env, &uln302.address);
897
+
898
+ // Now should be supported
899
+ assert!(uln302_client.is_supported_eid(&eid));
900
+
901
+ // Different EID should still not be supported
902
+ assert!(!uln302_client.is_supported_eid(&999u32));
903
+ }
904
+
905
+ #[test]
906
+ fn test_supported_eid_combinations_only_send_config() {
907
+ // Sui equivalent: test_supported_eid_combinations
908
+ // Tests various combinations of config presence - only send config set
909
+ let setup = setup();
910
+ let eid = 100u32;
911
+
912
+ // Only set send config
913
+ let config = UlnConfig::generate(&setup.env, 15, 2, 3, 2);
914
+ setup.set_default_send_uln_config(eid, config);
915
+
916
+ let TestSetup { env, uln302, .. } = setup;
917
+ let uln302_client = Uln302Client::new(&env, &uln302.address);
918
+
919
+ // Should NOT be supported (missing receive config)
920
+ assert!(!uln302_client.is_supported_eid(&eid));
921
+ }
922
+
923
+ #[test]
924
+ fn test_supported_eid_combinations_only_receive_config() {
925
+ // Sui equivalent: test_supported_eid_combinations
926
+ // Tests various combinations of config presence - only receive config set
927
+ let setup = setup();
928
+ let eid = 100u32;
929
+
930
+ // Only set receive config
931
+ let config = UlnConfig::generate(&setup.env, 15, 2, 3, 2);
932
+ setup.set_default_receive_uln_config(eid, config);
933
+
934
+ let TestSetup { env, uln302, .. } = setup;
935
+ let uln302_client = Uln302Client::new(&env, &uln302.address);
936
+
937
+ // Should NOT be supported (missing send config)
938
+ assert!(!uln302_client.is_supported_eid(&eid));
939
+ }
940
+
941
+ #[test]
942
+ fn test_supported_eid_combinations_both_configs() {
943
+ // Sui equivalent: test_supported_eid_combinations
944
+ // Tests that EID is supported only when both send AND receive configs are set
945
+ let setup = setup();
946
+ let eid = 100u32;
947
+
948
+ let config = UlnConfig::generate(&setup.env, 15, 2, 3, 2);
949
+
950
+ // First set only send config
951
+ setup.set_default_send_uln_config(eid, config.clone());
952
+
953
+ // Still not supported
954
+ assert!(!setup.uln302.is_supported_eid(&eid));
955
+
956
+ // Now set receive config too
957
+ setup.set_default_receive_uln_config(eid, config);
958
+
959
+ // Now fully supported
960
+ assert!(setup.uln302.is_supported_eid(&eid));
961
+ }
962
+
963
+ // ==================== Config Management Tests ====================
964
+
965
+ #[test]
966
+ fn test_config_management_comprehensive() {
967
+ // Sui equivalent: test_config_management
968
+ // Tests all config setters and getters in one focused test
969
+ let setup = setup();
970
+ let executor = setup.register_executable_address();
971
+
972
+ let eid = 42u32;
973
+ let executor_config = ExecutorConfig::new(50000, &executor);
974
+ let uln_config = UlnConfig::generate(&setup.env, 15, 2, 3, 2);
975
+
976
+ // Set default configs
977
+ setup.set_default_executor_config(eid, executor_config.clone());
978
+ setup.set_default_send_uln_config(eid, uln_config.clone());
979
+ setup.set_default_receive_uln_config(eid, uln_config.clone());
980
+
981
+ let TestSetup { uln302, .. } = setup;
982
+
983
+ // Verify executor config
984
+ let retrieved_executor = uln302.default_executor_config(&eid).unwrap();
985
+ assert_eq!(retrieved_executor.max_message_size, 50000);
986
+ assert_eq!(retrieved_executor.executor, executor);
987
+
988
+ // Verify send ULN config
989
+ let retrieved_send = uln302.default_send_uln_config(&eid).unwrap();
990
+ assert_eq!(retrieved_send.confirmations, 15);
991
+
992
+ // Verify receive ULN config
993
+ let retrieved_receive = uln302.default_receive_uln_config(&eid).unwrap();
994
+ assert_eq!(retrieved_receive.confirmations, 15);
995
+
996
+ // Verify EID is now supported
997
+ assert!(uln302.is_supported_eid(&eid));
998
+ }