@layerzerolabs/protocol-stellar-v2 0.2.19 → 0.2.21

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 (249) hide show
  1. package/.turbo/turbo-build.log +795 -791
  2. package/.turbo/turbo-lint.log +325 -155
  3. package/.turbo/turbo-test.log +1398 -1277
  4. package/Cargo.lock +122 -111
  5. package/Cargo.toml +32 -16
  6. package/contracts/common-macros/Cargo.toml +7 -7
  7. package/contracts/common-macros/src/auth.rs +18 -37
  8. package/contracts/common-macros/src/contract_ttl.rs +18 -7
  9. package/contracts/common-macros/src/lib.rs +31 -14
  10. package/contracts/common-macros/src/lz_contract.rs +38 -7
  11. package/contracts/common-macros/src/storage.rs +251 -292
  12. package/contracts/common-macros/src/tests/contract_ttl.rs +1 -1
  13. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__auth__snapshot_generated_multisig_code.snap +6 -12
  14. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__auth__snapshot_generated_ownable_code.snap +12 -17
  15. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__contract_ttl__snapshot_generated_contractimpl_code.snap +2 -1
  16. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__ttl_configurable__snapshot_generated_ttl_configurable_code.snap +2 -7
  17. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__upgradeable__snapshot_generated_upgradeable_code.snap +20 -14
  18. package/contracts/common-macros/src/tests/upgradeable.rs +26 -4
  19. package/contracts/common-macros/src/ttl_configurable.rs +2 -10
  20. package/contracts/common-macros/src/ttl_extendable.rs +2 -10
  21. package/contracts/common-macros/src/upgradeable.rs +61 -26
  22. package/contracts/common-macros/src/utils.rs +0 -9
  23. package/contracts/endpoint-v2/src/lib.rs +3 -2
  24. package/contracts/endpoint-v2/src/tests/endpoint_v2/clear.rs +2 -2
  25. package/contracts/endpoint-v2/src/tests/endpoint_v2/lz_receive_alert.rs +3 -3
  26. package/contracts/endpoint-v2/src/tests/endpoint_v2/send.rs +4 -4
  27. package/contracts/endpoint-v2/src/tests/endpoint_v2/set_delegate.rs +17 -5
  28. package/contracts/endpoint-v2/src/tests/endpoint_v2/set_zro.rs +4 -4
  29. package/contracts/endpoint-v2/src/tests/endpoint_v2/verify.rs +2 -2
  30. package/contracts/endpoint-v2/src/tests/message_lib_manager/register_library.rs +2 -2
  31. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_default_receive_lib_timeout.rs +6 -6
  32. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_default_receive_library.rs +67 -37
  33. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_default_send_library.rs +5 -5
  34. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_receive_library.rs +44 -54
  35. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_receive_library_timeout.rs +7 -7
  36. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_send_library.rs +8 -8
  37. package/contracts/endpoint-v2/src/tests/messaging_channel/burn.rs +3 -3
  38. package/contracts/endpoint-v2/src/tests/messaging_channel/nilify.rs +4 -4
  39. package/contracts/endpoint-v2/src/tests/messaging_channel/skip.rs +3 -3
  40. package/contracts/endpoint-v2/src/tests/messaging_composer/clear_compose.rs +2 -2
  41. package/contracts/endpoint-v2/src/tests/messaging_composer/lz_compose_alert.rs +3 -3
  42. package/contracts/endpoint-v2/src/tests/messaging_composer/send_compose.rs +2 -2
  43. package/contracts/layerzero-views/Cargo.toml +0 -1
  44. package/contracts/layerzero-views/src/layerzero_view.rs +1 -13
  45. package/contracts/macro-integration-tests/Cargo.toml +5 -15
  46. package/contracts/macro-integration-tests/tests/runtime/oapp/mod.rs +48 -0
  47. package/contracts/macro-integration-tests/tests/runtime/oapp/oapp_core.rs +170 -0
  48. package/contracts/macro-integration-tests/tests/runtime/oapp/options_type3.rs +154 -0
  49. package/contracts/macro-integration-tests/tests/runtime/oapp/receiver.rs +338 -0
  50. package/contracts/macro-integration-tests/tests/runtime/oapp/sender.rs +435 -0
  51. package/contracts/macro-integration-tests/tests/runtime.rs +1 -0
  52. package/contracts/macro-integration-tests/tests/ui/oapp/fail/custom_wrong_value.rs +8 -0
  53. package/contracts/macro-integration-tests/tests/ui/oapp/fail/custom_wrong_value.stderr +5 -0
  54. package/contracts/macro-integration-tests/tests/ui/oapp/fail/missing_lz_receive_internal.rs +8 -0
  55. package/contracts/macro-integration-tests/tests/ui/oapp/fail/missing_lz_receive_internal.stderr +71 -0
  56. package/contracts/macro-integration-tests/tests/ui/oapp/fail/non_struct_input.rs +10 -0
  57. package/contracts/macro-integration-tests/tests/ui/oapp/fail/non_struct_input.stderr +5 -0
  58. package/contracts/macro-integration-tests/tests/ui/oapp/fail/unknown_custom_option.rs +8 -0
  59. package/contracts/macro-integration-tests/tests/ui/oapp/fail/unknown_custom_option.stderr +5 -0
  60. package/contracts/macro-integration-tests/tests/ui/oapp/fail/wrong_key.rs +8 -0
  61. package/contracts/macro-integration-tests/tests/ui/oapp/fail/wrong_key.stderr +5 -0
  62. package/contracts/macro-integration-tests/tests/ui/oapp/pass/custom_all.rs +38 -0
  63. package/contracts/macro-integration-tests/tests/ui/oapp/pass/custom_single_trait.rs +96 -0
  64. package/contracts/macro-integration-tests/tests/ui/oapp/pass/minimal_contract.rs +64 -0
  65. package/contracts/macro-integration-tests/tests/ui/oapp/pass/struct_with_fields.rs +46 -0
  66. package/contracts/macro-integration-tests/tests/ui/ownable/fail/only_auth_missing_env.stderr +8 -0
  67. package/contracts/macro-integration-tests/tests/ui/ownable/pass/namespacing_and_imports.rs +1 -1
  68. package/contracts/macro-integration-tests/tests/ui/ownable/pass/only_auth_env_param_variants.rs +1 -1
  69. package/contracts/macro-integration-tests/tests/ui_oapp.rs +11 -0
  70. package/contracts/message-libs/message-lib-common/Cargo.toml +0 -1
  71. package/contracts/message-libs/message-lib-common/src/errors.rs +1 -1
  72. package/contracts/message-libs/treasury/Cargo.toml +0 -2
  73. package/contracts/message-libs/treasury/src/tests/treasury_tests.rs +2 -2
  74. package/contracts/message-libs/uln-302/src/events.rs +4 -0
  75. package/contracts/message-libs/uln-302/src/send_uln.rs +22 -6
  76. package/contracts/message-libs/uln-302/src/tests/receive_uln302/effective_receive_uln_config.rs +2 -2
  77. package/contracts/message-libs/uln-302/src/tests/receive_uln302/set_default_receive_uln_configs.rs +2 -2
  78. package/contracts/message-libs/uln-302/src/tests/receive_uln302/verify.rs +2 -2
  79. package/contracts/message-libs/uln-302/src/tests/send_uln302/effective_executor_config.rs +2 -2
  80. package/contracts/message-libs/uln-302/src/tests/send_uln302/effective_send_uln_config.rs +2 -2
  81. package/contracts/message-libs/uln-302/src/tests/send_uln302/send.rs +21 -67
  82. package/contracts/message-libs/uln-302/src/tests/send_uln302/set_default_executor_configs.rs +2 -2
  83. package/contracts/message-libs/uln-302/src/tests/send_uln302/set_default_send_uln_configs.rs +2 -2
  84. package/contracts/oapps/counter/Cargo.toml +5 -6
  85. package/contracts/oapps/counter/integration_tests/setup_uln.rs +1 -1
  86. package/contracts/oapps/counter/integration_tests/utils.rs +19 -12
  87. package/contracts/oapps/oapp/src/errors.rs +1 -1
  88. package/contracts/oapps/oapp/src/interfaces/mod.rs +3 -0
  89. package/contracts/oapps/oapp/src/interfaces/oapp_msg_inspector.rs +47 -0
  90. package/contracts/oapps/oapp/src/lib.rs +1 -0
  91. package/contracts/oapps/oapp/src/macro_tests/test_macros.rs +4 -4
  92. package/contracts/oapps/oapp/src/oapp_core.rs +5 -5
  93. package/contracts/oapps/oapp/src/oapp_options_type3.rs +12 -4
  94. package/contracts/oapps/oapp/src/oapp_receiver.rs +14 -9
  95. package/contracts/oapps/oapp/src/tests/mod.rs +4 -4
  96. package/contracts/oapps/oapp/src/tests/oapp_core.rs +223 -0
  97. package/contracts/oapps/oapp/src/tests/oapp_options_type3.rs +240 -0
  98. package/contracts/oapps/oapp/src/tests/oapp_receiver.rs +381 -0
  99. package/contracts/oapps/oapp/src/tests/oapp_sender.rs +569 -0
  100. package/contracts/oapps/oapp-macros/Cargo.toml +8 -4
  101. package/contracts/oapps/oapp-macros/src/generators.rs +9 -34
  102. package/contracts/oapps/oapp-macros/src/lib.rs +3 -0
  103. package/contracts/oapps/oapp-macros/src/tests/mod.rs +2 -0
  104. package/contracts/oapps/oapp-macros/src/tests/oapp.rs +88 -0
  105. package/contracts/oapps/oapp-macros/src/tests/parse_custom_impls.rs +86 -0
  106. package/contracts/oapps/oapp-macros/src/tests/snapshots/oapp_macros__tests__oapp__snapshot_generate_oapp.snap +103 -0
  107. package/contracts/oapps/oft/integration-tests/utils.rs +28 -8
  108. package/contracts/oapps/oft/src/extensions/oft_fee.rs +153 -75
  109. package/contracts/oapps/oft/src/extensions/pausable.rs +61 -12
  110. package/contracts/oapps/oft/src/extensions/rate_limiter.rs +198 -134
  111. package/contracts/oapps/oft/src/oft.rs +45 -50
  112. package/contracts/oapps/oft/src/oft_types/lock_unlock.rs +1 -1
  113. package/contracts/oapps/oft/src/oft_types/mint_burn.rs +4 -26
  114. package/contracts/oapps/oft-core/Cargo.toml +1 -4
  115. package/contracts/oapps/oft-core/integration-tests/setup.rs +3 -3
  116. package/contracts/oapps/oft-core/integration-tests/utils.rs +21 -3
  117. package/contracts/oapps/oft-core/src/errors.rs +3 -2
  118. package/contracts/oapps/oft-core/src/events.rs +6 -0
  119. package/contracts/oapps/oft-core/src/lib.rs +1 -1
  120. package/contracts/oapps/oft-core/src/oft_core.rs +341 -246
  121. package/contracts/oapps/oft-core/src/storage.rs +7 -3
  122. package/contracts/oapps/oft-core/src/tests/mod.rs +1 -0
  123. package/contracts/oapps/oft-core/src/tests/test_decimals.rs +37 -2
  124. package/contracts/oapps/oft-core/src/tests/test_lz_receive.rs +2 -2
  125. package/contracts/oapps/oft-core/src/tests/test_msg_inspector.rs +323 -0
  126. package/contracts/oapps/oft-core/src/tests/test_send.rs +2 -2
  127. package/contracts/oapps/oft-core/src/tests/test_utils.rs +61 -16
  128. package/contracts/upgrader/src/lib.rs +30 -57
  129. package/contracts/upgrader/src/tests/test_data/test_upgradeable_contract1.wasm +0 -0
  130. package/contracts/upgrader/src/tests/test_data/test_upgradeable_contract2.wasm +0 -0
  131. package/contracts/upgrader/src/tests/test_upgrader.rs +44 -35
  132. package/contracts/utils/Cargo.toml +0 -1
  133. package/contracts/utils/src/buffer_reader.rs +1 -0
  134. package/contracts/utils/src/errors.rs +4 -2
  135. package/contracts/utils/src/multisig.rs +17 -8
  136. package/contracts/utils/src/ownable.rs +6 -6
  137. package/contracts/utils/src/testing_utils.rs +124 -54
  138. package/contracts/utils/src/tests/multisig.rs +12 -12
  139. package/contracts/utils/src/tests/ownable.rs +6 -6
  140. package/contracts/utils/src/tests/testing_utils.rs +50 -167
  141. package/contracts/utils/src/tests/ttl_configurable.rs +5 -5
  142. package/contracts/utils/src/tests/upgradeable.rs +372 -175
  143. package/contracts/utils/src/ttl_configurable.rs +13 -7
  144. package/contracts/utils/src/upgradeable.rs +48 -23
  145. package/contracts/workers/dvn/Cargo.toml +6 -6
  146. package/contracts/workers/dvn/src/auth.rs +12 -42
  147. package/contracts/workers/dvn/src/dvn.rs +15 -40
  148. package/contracts/workers/dvn/src/errors.rs +0 -1
  149. package/contracts/workers/dvn/src/interfaces/dvn.rs +35 -0
  150. package/contracts/workers/dvn/src/lib.rs +4 -3
  151. package/contracts/workers/dvn/src/tests/auth.rs +1 -1
  152. package/contracts/workers/dvn/src/tests/dvn.rs +19 -15
  153. package/contracts/workers/dvn/src/tests/multisig/set_threshold.rs +2 -4
  154. package/contracts/workers/dvn/src/tests/multisig/verify_signatures.rs +1 -3
  155. package/contracts/workers/dvn/src/tests/setup.rs +5 -9
  156. package/contracts/workers/dvn-fee-lib/Cargo.toml +2 -2
  157. package/contracts/workers/dvn-fee-lib/src/dvn_fee_lib.rs +38 -22
  158. package/contracts/workers/dvn-fee-lib/src/lib.rs +12 -2
  159. package/contracts/workers/dvn-fee-lib/src/tests/dvn_fee_lib.rs +17 -16
  160. package/contracts/workers/executor/Cargo.toml +4 -0
  161. package/contracts/workers/executor/src/executor.rs +15 -36
  162. package/contracts/workers/executor/src/lib.rs +2 -2
  163. package/contracts/workers/executor/src/tests/auth.rs +394 -0
  164. package/contracts/workers/executor/src/tests/executor.rs +410 -0
  165. package/contracts/workers/executor/src/tests/mod.rs +3 -0
  166. package/contracts/workers/executor/src/tests/setup.rs +250 -0
  167. package/contracts/workers/executor-fee-lib/Cargo.toml +7 -1
  168. package/contracts/workers/executor-fee-lib/src/executor_fee_lib.rs +62 -15
  169. package/contracts/workers/executor-fee-lib/src/executor_option.rs +28 -1
  170. package/contracts/workers/executor-fee-lib/src/lib.rs +11 -2
  171. package/contracts/workers/executor-fee-lib/src/tests/executor_fee_lib.rs +701 -0
  172. package/contracts/workers/executor-fee-lib/src/tests/executor_option.rs +370 -0
  173. package/contracts/workers/executor-fee-lib/src/tests/mod.rs +4 -0
  174. package/contracts/workers/executor-fee-lib/src/tests/setup.rs +60 -0
  175. package/contracts/workers/executor-helper/Cargo.toml +0 -1
  176. package/contracts/workers/executor-helper/src/lib.rs +3 -0
  177. package/contracts/workers/executor-helper/src/tests/executor_helper.rs +184 -0
  178. package/contracts/workers/executor-helper/src/tests/mod.rs +2 -0
  179. package/contracts/workers/executor-helper/src/tests/setup.rs +366 -0
  180. package/contracts/workers/fee-lib-interfaces/Cargo.toml +14 -0
  181. package/contracts/workers/{worker/src/interfaces/mod.rs → fee-lib-interfaces/src/lib.rs} +4 -3
  182. package/contracts/workers/price-feed/Cargo.toml +7 -1
  183. package/contracts/workers/price-feed/src/events.rs +1 -1
  184. package/contracts/workers/price-feed/src/lib.rs +12 -4
  185. package/contracts/workers/price-feed/src/price_feed.rs +5 -21
  186. package/contracts/workers/price-feed/src/storage.rs +1 -1
  187. package/contracts/workers/price-feed/src/tests/mod.rs +2 -0
  188. package/contracts/workers/price-feed/src/tests/price_feed.rs +869 -0
  189. package/contracts/workers/price-feed/src/tests/setup.rs +70 -0
  190. package/contracts/workers/price-feed/src/types.rs +1 -1
  191. package/contracts/workers/worker/src/errors.rs +1 -4
  192. package/contracts/workers/worker/src/lib.rs +0 -2
  193. package/contracts/workers/worker/src/storage.rs +32 -29
  194. package/contracts/workers/worker/src/tests/setup.rs +2 -8
  195. package/contracts/workers/worker/src/tests/worker.rs +96 -74
  196. package/contracts/workers/worker/src/worker.rs +75 -75
  197. package/docs/error-spec.md +55 -0
  198. package/docs/layerzero-v2-on-stellar.md +447 -0
  199. package/docs/oapp-guide.md +212 -0
  200. package/docs/oft-guide.md +314 -0
  201. package/package.json +3 -3
  202. package/sdk/.turbo/turbo-test.log +268 -263
  203. package/sdk/dist/generated/bml.d.ts +12 -4
  204. package/sdk/dist/generated/bml.js +9 -7
  205. package/sdk/dist/generated/counter.d.ts +306 -298
  206. package/sdk/dist/generated/counter.js +48 -46
  207. package/sdk/dist/generated/dvn.d.ts +450 -411
  208. package/sdk/dist/generated/dvn.js +66 -64
  209. package/sdk/dist/generated/dvn_fee_lib.d.ts +294 -338
  210. package/sdk/dist/generated/dvn_fee_lib.js +33 -64
  211. package/sdk/dist/generated/endpoint.d.ts +108 -100
  212. package/sdk/dist/generated/endpoint.js +21 -19
  213. package/sdk/dist/generated/executor.d.ts +414 -370
  214. package/sdk/dist/generated/executor.js +58 -55
  215. package/sdk/dist/generated/executor_fee_lib.d.ts +333 -377
  216. package/sdk/dist/generated/executor_fee_lib.js +34 -65
  217. package/sdk/dist/generated/executor_helper.d.ts +26 -190
  218. package/sdk/dist/generated/executor_helper.js +23 -28
  219. package/sdk/dist/generated/layerzero_view.d.ts +1271 -0
  220. package/sdk/dist/generated/layerzero_view.js +294 -0
  221. package/sdk/dist/generated/oft.d.ts +408 -385
  222. package/sdk/dist/generated/oft.js +89 -92
  223. package/sdk/dist/generated/price_feed.d.ts +385 -429
  224. package/sdk/dist/generated/price_feed.js +50 -81
  225. package/sdk/dist/generated/sml.d.ts +108 -100
  226. package/sdk/dist/generated/sml.js +21 -19
  227. package/sdk/dist/generated/treasury.d.ts +108 -100
  228. package/sdk/dist/generated/treasury.js +21 -19
  229. package/sdk/dist/generated/uln302.d.ts +108 -100
  230. package/sdk/dist/generated/uln302.js +23 -21
  231. package/sdk/dist/generated/upgrader.d.ts +189 -18
  232. package/sdk/dist/generated/upgrader.js +84 -4
  233. package/sdk/dist/index.d.ts +1 -0
  234. package/sdk/dist/index.js +2 -0
  235. package/sdk/package.json +1 -1
  236. package/sdk/src/index.ts +3 -0
  237. package/sdk/test/oft-sml.test.ts +4 -4
  238. package/sdk/test/suites/localnet.ts +84 -20
  239. package/sdk/test/upgrader.test.ts +2 -3
  240. package/tools/ts-bindings-gen/src/main.rs +2 -1
  241. package/contracts/ERROR_SPEC.md +0 -44
  242. package/contracts/endpoint-v2/ARCHITECTURE.md +0 -233
  243. package/contracts/oapps/oapp/src/tests/test_oapp_core.rs +0 -175
  244. package/contracts/oapps/oapp/src/tests/test_oapp_options_type3.rs +0 -212
  245. package/contracts/oapps/oapp/src/tests/test_oapp_receiver.rs +0 -153
  246. package/contracts/oapps/oapp/src/tests/test_oapp_sender.rs +0 -294
  247. /package/contracts/workers/{worker/src/interfaces → fee-lib-interfaces/src}/dvn_fee_lib.rs +0 -0
  248. /package/contracts/workers/{worker/src/interfaces → fee-lib-interfaces/src}/executor_fee_lib.rs +0 -0
  249. /package/contracts/workers/{worker/src/interfaces → fee-lib-interfaces/src}/price_feed.rs +0 -0
@@ -0,0 +1,370 @@
1
+ use soroban_sdk::{Bytes, Env};
2
+
3
+ use crate::executor_option;
4
+
5
+ use super::setup::{
6
+ bytes32, option_header, option_lz_compose, option_lz_receive, option_native_drop, option_ordered_execution,
7
+ };
8
+
9
+ // parse_executor_options
10
+
11
+ #[test]
12
+ fn test_parse_executor_options_aggregates_values() {
13
+ let env = Env::default();
14
+ let receiver = bytes32(&env, 0x11);
15
+
16
+ let mut options = Bytes::new(&env);
17
+ options.append(&option_lz_receive(&env, 10, Some(2))); // gas=10, value=2
18
+ options.append(&option_native_drop(&env, 5, &receiver)); // value=5
19
+ options.append(&option_lz_compose(&env, 0, 7, Some(3))); // gas=7, value=3
20
+ options.append(&option_ordered_execution(&env)); // flag only
21
+
22
+ let agg = executor_option::parse_executor_options(&env, &options, false, 1_000);
23
+ assert_eq!(agg.total_gas, 17); // 10 + 7
24
+ assert_eq!(agg.total_value, 10); // 2 + 5 + 3
25
+ assert_eq!(agg.num_lz_compose, 1);
26
+ assert_eq!(agg.ordered, true);
27
+ }
28
+
29
+ #[test]
30
+ fn test_parse_executor_options_counts_multiple_lz_compose() {
31
+ let env = Env::default();
32
+
33
+ let mut options = Bytes::new(&env);
34
+ options.append(&option_lz_receive(&env, 10, None));
35
+ options.append(&option_lz_compose(&env, 0, 7, None));
36
+ options.append(&option_lz_compose(&env, 1, 8, Some(1)));
37
+
38
+ let agg = executor_option::parse_executor_options(&env, &options, false, 1_000);
39
+ assert_eq!(agg.num_lz_compose, 2);
40
+ assert_eq!(agg.total_gas, 25); // 10 + 7 + 8
41
+ assert_eq!(agg.total_value, 1); // only compose value
42
+ }
43
+
44
+ #[test]
45
+ fn test_parse_executor_options_accumulates_multiple_lz_receive_gas_and_value() {
46
+ let env = Env::default();
47
+
48
+ let mut options = Bytes::new(&env);
49
+ options.append(&option_lz_receive(&env, 10, Some(2))); // gas=10, value=2
50
+ options.append(&option_lz_receive(&env, 20, Some(3))); // gas=20, value=3
51
+
52
+ let agg = executor_option::parse_executor_options(&env, &options, false, 1_000);
53
+ assert_eq!(agg.total_gas, 30);
54
+ assert_eq!(agg.total_value, 5);
55
+ assert_eq!(agg.num_lz_compose, 0);
56
+ assert_eq!(agg.ordered, false);
57
+ }
58
+
59
+ #[test]
60
+ fn test_parse_executor_options_allows_total_value_equal_to_native_cap() {
61
+ let env = Env::default();
62
+ let receiver = bytes32(&env, 0x33);
63
+
64
+ // total_value = lzReceive.value(50) + nativeDrop(50) = 100, cap=100 should pass (<=).
65
+ let mut options = Bytes::new(&env);
66
+ options.append(&option_lz_receive(&env, 1, Some(50)));
67
+ options.append(&option_native_drop(&env, 50, &receiver));
68
+
69
+ let agg = executor_option::parse_executor_options(&env, &options, false, 100);
70
+ assert_eq!(agg.total_value, 100);
71
+ assert_eq!(agg.total_gas, 1);
72
+ }
73
+
74
+ #[test]
75
+ #[should_panic(expected = "Error(Contract, #8)")] // ExecutorFeeLibError::NoOptions
76
+ fn test_parse_executor_options_no_options() {
77
+ let env = Env::default();
78
+ executor_option::parse_executor_options(&env, &Bytes::new(&env), false, 1_000);
79
+ }
80
+
81
+ #[test]
82
+ #[should_panic(expected = "Error(Contract, #5)")] // ExecutorFeeLibError::InvalidLzReceiveOption
83
+ fn test_parse_executor_options_rejects_invalid_lz_receive_payload_length() {
84
+ let env = Env::default();
85
+ let mut options = Bytes::new(&env);
86
+
87
+ // Bad lzReceive payload (15 bytes instead of 16 or 32). Still wrapped in a valid option header.
88
+ let bad = Bytes::from_slice(&env, &[0u8; 15]);
89
+ options.append(&option_header(&env, message_lib_common::worker_options::EXECUTOR_OPTION_TYPE_LZRECEIVE, bad));
90
+
91
+ executor_option::parse_executor_options(&env, &options, false, 1_000);
92
+ }
93
+
94
+ #[test]
95
+ #[should_panic(expected = "Error(Contract, #6)")] // ExecutorFeeLibError::InvalidNativeDropOption
96
+ fn test_parse_executor_options_rejects_invalid_native_drop_payload_length() {
97
+ let env = Env::default();
98
+ let mut options = Bytes::new(&env);
99
+
100
+ // Need a non-zero lzReceive gas, otherwise we'd fail with ZeroLzReceiveGasProvided first.
101
+ options.append(&option_lz_receive(&env, 1, None));
102
+
103
+ // Bad nativeDrop payload (47 bytes instead of 48).
104
+ let bad = Bytes::from_slice(&env, &[0u8; 47]);
105
+ options.append(&option_header(&env, message_lib_common::worker_options::EXECUTOR_OPTION_TYPE_NATIVE_DROP, bad));
106
+
107
+ executor_option::parse_executor_options(&env, &options, false, 1_000);
108
+ }
109
+
110
+ #[test]
111
+ #[should_panic(expected = "Error(Contract, #4)")] // ExecutorFeeLibError::InvalidLzComposeOption
112
+ fn test_parse_executor_options_rejects_invalid_lz_compose_payload_length() {
113
+ let env = Env::default();
114
+ let mut options = Bytes::new(&env);
115
+
116
+ // Need a non-zero lzReceive gas, otherwise we'd fail with ZeroLzReceiveGasProvided first.
117
+ options.append(&option_lz_receive(&env, 1, None));
118
+
119
+ // Bad lzCompose payload (17 bytes instead of 18 or 34).
120
+ let bad = Bytes::from_slice(&env, &[0u8; 17]);
121
+ options.append(&option_header(&env, crate::executor_option::EXECUTOR_OPTION_TYPE_LZCOMPOSE, bad));
122
+
123
+ executor_option::parse_executor_options(&env, &options, false, 1_000);
124
+ }
125
+
126
+ #[test]
127
+ #[should_panic(expected = "Error(Contract, #10)")] // ExecutorFeeLibError::UnsupportedOptionType
128
+ fn test_parse_executor_options_v1_rejects_lz_receive_with_value() {
129
+ let env = Env::default();
130
+
131
+ let mut options = Bytes::new(&env);
132
+ options.append(&option_lz_receive(&env, 1, Some(1)));
133
+
134
+ executor_option::parse_executor_options(&env, &options, true, 1_000);
135
+ }
136
+
137
+ #[test]
138
+ #[should_panic(expected = "Error(Contract, #10)")] // ExecutorFeeLibError::UnsupportedOptionType
139
+ fn test_parse_executor_options_v1_rejects_lz_compose() {
140
+ let env = Env::default();
141
+
142
+ let mut options = Bytes::new(&env);
143
+ options.append(&option_lz_receive(&env, 1, None));
144
+ options.append(&option_lz_compose(&env, 0, 1, None));
145
+
146
+ executor_option::parse_executor_options(&env, &options, true, 1_000);
147
+ }
148
+
149
+ #[test]
150
+ #[should_panic(expected = "Error(Contract, #11)")] // ExecutorFeeLibError::ZeroLzComposeGasProvided
151
+ fn test_parse_executor_options_zero_lz_compose_gas() {
152
+ let env = Env::default();
153
+
154
+ let mut options = Bytes::new(&env);
155
+ options.append(&option_lz_receive(&env, 1, None));
156
+ options.append(&option_lz_compose(&env, 0, 0, None));
157
+
158
+ executor_option::parse_executor_options(&env, &options, false, 1_000);
159
+ }
160
+
161
+ #[test]
162
+ #[should_panic(expected = "Error(Contract, #10)")] // ExecutorFeeLibError::UnsupportedOptionType
163
+ fn test_parse_executor_options_unknown_option_type() {
164
+ let env = Env::default();
165
+
166
+ let mut options = Bytes::new(&env);
167
+ options.append(&option_lz_receive(&env, 1, None));
168
+ options.append(&option_header(&env, 0xFE, Bytes::new(&env)));
169
+
170
+ executor_option::parse_executor_options(&env, &options, false, 1_000);
171
+ }
172
+
173
+ #[test]
174
+ #[should_panic(expected = "Error(Contract, #7)")] // ExecutorFeeLibError::NativeAmountExceedsCap
175
+ fn test_parse_executor_options_native_amount_exceeds_cap() {
176
+ let env = Env::default();
177
+ let receiver = bytes32(&env, 0x22);
178
+
179
+ let mut options = Bytes::new(&env);
180
+ options.append(&option_lz_receive(&env, 1, None));
181
+ options.append(&option_native_drop(&env, 101, &receiver)); // cap=100
182
+
183
+ executor_option::parse_executor_options(&env, &options, false, 100);
184
+ }
185
+
186
+ #[test]
187
+ #[should_panic(expected = "Error(Contract, #12)")] // ExecutorFeeLibError::ZeroLzReceiveGasProvided
188
+ fn test_parse_executor_options_zero_lz_receive_gas() {
189
+ let env = Env::default();
190
+ let options = option_ordered_execution(&env);
191
+ executor_option::parse_executor_options(&env, &options, false, 1_000);
192
+ }
193
+
194
+ #[test]
195
+ #[should_panic(expected = "Error(Contract, #12)")] // ExecutorFeeLibError::ZeroLzReceiveGasProvided
196
+ fn test_parse_executor_options_treats_zero_lz_receive_gas_as_missing() {
197
+ let env = Env::default();
198
+ let mut options = Bytes::new(&env);
199
+ options.append(&option_lz_receive(&env, 0, None)); // lzReceive present but gas=0
200
+ executor_option::parse_executor_options(&env, &options, false, 1_000);
201
+ }
202
+
203
+ // next_executor_option
204
+
205
+ #[test]
206
+ fn test_next_executor_option() {
207
+ let env = Env::default();
208
+
209
+ // Extract option type and data correctly
210
+ let data = Bytes::from_slice(&env, &[0x01, 0x02]);
211
+ let option = option_header(&env, 1, data.clone()); // type 1
212
+ let mut reader = utils::buffer_reader::BufferReader::new(&option);
213
+ let (option_type, option_data) = executor_option::test::next_executor_option_for_test(&mut reader);
214
+ assert_eq!(option_type, 1);
215
+ assert_eq!(option_data.len(), 2);
216
+ assert_eq!(option_data.get(0).unwrap(), 0x01);
217
+ assert_eq!(option_data.get(1).unwrap(), 0x02);
218
+ }
219
+
220
+ #[test]
221
+ #[should_panic(expected = "Error(Contract, #1000)")] // BufferReaderError::InvalidLength (wrapped option_size)
222
+ fn test_next_executor_option_rejects_zero_option_size() {
223
+ let env = Env::default();
224
+ use utils::buffer_writer::BufferWriter;
225
+
226
+ // [worker_id=1][option_size=0][...]
227
+ let mut w = BufferWriter::new(&env);
228
+ w.write_u8(super::setup::EXECUTOR_WORKER_ID).write_u16(0);
229
+ let raw = w.to_bytes();
230
+
231
+ let mut reader = utils::buffer_reader::BufferReader::new(&raw);
232
+ let _ = executor_option::test::next_executor_option_for_test(&mut reader);
233
+ }
234
+
235
+ // next_executor_option (invalid/truncated)
236
+
237
+ #[test]
238
+ #[should_panic(expected = "Error(Contract, #1000)")] // BufferReaderError::InvalidLength
239
+ fn test_next_executor_option_rejects_truncated_option_data() {
240
+ let env = Env::default();
241
+ use utils::buffer_writer::BufferWriter;
242
+
243
+ // Claims option_size=3 => [option_type (1) + option_data (2)]
244
+ // But we only provide option_type and 1 byte of data => truncated.
245
+ let mut w = BufferWriter::new(&env);
246
+ w.write_u8(super::setup::EXECUTOR_WORKER_ID)
247
+ .write_u16(3)
248
+ .write_u8(0xAA) // option_type
249
+ .write_u8(0x01); // only 1 byte data (should be 2)
250
+ let raw = w.to_bytes();
251
+
252
+ let mut reader = utils::buffer_reader::BufferReader::new(&raw);
253
+ let _ = executor_option::test::next_executor_option_for_test(&mut reader);
254
+ }
255
+
256
+ // decode_lz_receive_option
257
+
258
+ #[test]
259
+ fn test_decode_lz_receive_option() {
260
+ let env = Env::default();
261
+ use utils::buffer_writer::BufferWriter;
262
+
263
+ // 16 bytes: gas only
264
+ let mut w = BufferWriter::new(&env);
265
+ w.write_u128(1);
266
+ let (gas, value) = executor_option::test::decode_lz_receive_option_for_test(&env, &w.to_bytes());
267
+ assert_eq!(gas, 1);
268
+ assert_eq!(value, 0);
269
+
270
+ // 32 bytes: gas + value
271
+ let mut w = BufferWriter::new(&env);
272
+ w.write_u128(1).write_u128(2);
273
+ let (gas, value) = executor_option::test::decode_lz_receive_option_for_test(&env, &w.to_bytes());
274
+ assert_eq!(gas, 1);
275
+ assert_eq!(value, 2);
276
+ }
277
+
278
+ #[test]
279
+ #[should_panic(expected = "Error(Contract, #5)")] // ExecutorFeeLibError::InvalidLzReceiveOption
280
+ fn test_decode_lz_receive_option_invalid_length_15() {
281
+ let env = Env::default();
282
+ // Invalid length: 15 bytes (not 16 or 32)
283
+ let bad = Bytes::from_slice(&env, &[0u8; 15]);
284
+ let _ = executor_option::test::decode_lz_receive_option_for_test(&env, &bad);
285
+ }
286
+
287
+ #[test]
288
+ #[should_panic(expected = "Error(Contract, #5)")] // ExecutorFeeLibError::InvalidLzReceiveOption
289
+ fn test_decode_lz_receive_option_invalid_length_33() {
290
+ let env = Env::default();
291
+ // Invalid length: 33 bytes (not 16 or 32)
292
+ let bad = Bytes::from_slice(&env, &[0u8; 33]);
293
+ let _ = executor_option::test::decode_lz_receive_option_for_test(&env, &bad);
294
+ }
295
+
296
+ // decode_native_drop_option
297
+
298
+ #[test]
299
+ fn test_decode_native_drop_option() {
300
+ let env = Env::default();
301
+ use utils::buffer_writer::BufferWriter;
302
+
303
+ // 48 bytes: amount + receiver
304
+ let receiver = bytes32(&env, 0x12);
305
+ let mut w = BufferWriter::new(&env);
306
+ w.write_u128(1).write_bytes_n(&receiver);
307
+ let (amount, recv) = executor_option::test::decode_native_drop_option_for_test(&env, &w.to_bytes());
308
+ assert_eq!(amount, 1);
309
+ assert_eq!(recv, receiver);
310
+ }
311
+
312
+ #[test]
313
+ #[should_panic(expected = "Error(Contract, #6)")] // ExecutorFeeLibError::InvalidNativeDropOption
314
+ fn test_decode_native_drop_option_invalid_length_47() {
315
+ let env = Env::default();
316
+ // Invalid length: 47 bytes (not 48)
317
+ let bad = Bytes::from_slice(&env, &[0u8; 47]);
318
+ let _ = executor_option::test::decode_native_drop_option_for_test(&env, &bad);
319
+ }
320
+
321
+ #[test]
322
+ #[should_panic(expected = "Error(Contract, #6)")] // ExecutorFeeLibError::InvalidNativeDropOption
323
+ fn test_decode_native_drop_option_invalid_length_49() {
324
+ let env = Env::default();
325
+ // Invalid length: 49 bytes (not 48)
326
+ let bad = Bytes::from_slice(&env, &[0u8; 49]);
327
+ let _ = executor_option::test::decode_native_drop_option_for_test(&env, &bad);
328
+ }
329
+
330
+ // decode_lz_compose_option
331
+
332
+ #[test]
333
+ fn test_decode_lz_compose_option() {
334
+ let env = Env::default();
335
+ use utils::buffer_writer::BufferWriter;
336
+
337
+ // 18 bytes: index + gas (no value)
338
+ let mut w = BufferWriter::new(&env);
339
+ w.write_u16(0).write_u128(1);
340
+ let (index, gas, value) = executor_option::test::decode_lz_compose_option_for_test(&env, &w.to_bytes());
341
+ assert_eq!(index, 0);
342
+ assert_eq!(gas, 1);
343
+ assert_eq!(value, 0);
344
+
345
+ // 34 bytes: index + gas + value
346
+ let mut w = BufferWriter::new(&env);
347
+ w.write_u16(0).write_u128(1).write_u128(2);
348
+ let (index, gas, value) = executor_option::test::decode_lz_compose_option_for_test(&env, &w.to_bytes());
349
+ assert_eq!(index, 0);
350
+ assert_eq!(gas, 1);
351
+ assert_eq!(value, 2);
352
+ }
353
+
354
+ #[test]
355
+ #[should_panic(expected = "Error(Contract, #4)")] // ExecutorFeeLibError::InvalidLzComposeOption
356
+ fn test_decode_lz_compose_option_invalid_length_17() {
357
+ let env = Env::default();
358
+ // Invalid length: 17 bytes (not 18 or 34) - InvalidLzComposeOption
359
+ let bad = Bytes::from_slice(&env, &[0u8; 17]);
360
+ let _ = executor_option::test::decode_lz_compose_option_for_test(&env, &bad);
361
+ }
362
+
363
+ #[test]
364
+ #[should_panic(expected = "Error(Contract, #4)")] // ExecutorFeeLibError::InvalidLzComposeOption
365
+ fn test_decode_lz_compose_option_invalid_length_35() {
366
+ let env = Env::default();
367
+ // Invalid length: 35 bytes (not 18 or 34) - InvalidLzComposeOption
368
+ let bad = Bytes::from_slice(&env, &[0u8; 35]);
369
+ let _ = executor_option::test::decode_lz_compose_option_for_test(&env, &bad);
370
+ }
@@ -0,0 +1,4 @@
1
+ mod setup;
2
+
3
+ mod executor_fee_lib;
4
+ mod executor_option;
@@ -0,0 +1,60 @@
1
+ use soroban_sdk::{testutils::Address as _, Address, Bytes, BytesN, Env};
2
+ use utils::buffer_writer::BufferWriter;
3
+
4
+ use crate::{ExecutorFeeLib, ExecutorFeeLibClient};
5
+
6
+ pub const EXECUTOR_WORKER_ID: u8 = 1;
7
+
8
+ pub struct TestSetup<'a> {
9
+ pub env: Env,
10
+ pub client: ExecutorFeeLibClient<'a>,
11
+ }
12
+
13
+ impl<'a> TestSetup<'a> {
14
+ pub fn new() -> Self {
15
+ let env = Env::default();
16
+ let owner = Address::generate(&env);
17
+ let contract_id = env.register(ExecutorFeeLib, (&owner,));
18
+ let client = ExecutorFeeLibClient::new(&env, &contract_id);
19
+ Self { env, client }
20
+ }
21
+ }
22
+
23
+ pub fn bytes32(env: &Env, fill: u8) -> BytesN<32> {
24
+ BytesN::from_array(env, &[fill; 32])
25
+ }
26
+
27
+ pub fn option_header(env: &Env, option_type: u8, option_data: Bytes) -> Bytes {
28
+ let mut w = BufferWriter::new(env);
29
+ let option_size = 1u16 + (option_data.len() as u16);
30
+ w.write_u8(EXECUTOR_WORKER_ID).write_u16(option_size).write_u8(option_type).write_bytes(&option_data);
31
+ w.to_bytes()
32
+ }
33
+
34
+ pub fn option_lz_receive(env: &Env, gas: u128, value: Option<u128>) -> Bytes {
35
+ let mut w = BufferWriter::new(env);
36
+ w.write_u128(gas);
37
+ if let Some(v) = value {
38
+ w.write_u128(v);
39
+ }
40
+ option_header(env, message_lib_common::worker_options::EXECUTOR_OPTION_TYPE_LZRECEIVE, w.to_bytes())
41
+ }
42
+
43
+ pub fn option_native_drop(env: &Env, amount: u128, receiver: &BytesN<32>) -> Bytes {
44
+ let mut w = BufferWriter::new(env);
45
+ w.write_u128(amount).write_bytes_n(receiver);
46
+ option_header(env, message_lib_common::worker_options::EXECUTOR_OPTION_TYPE_NATIVE_DROP, w.to_bytes())
47
+ }
48
+
49
+ pub fn option_lz_compose(env: &Env, index: u16, gas: u128, value: Option<u128>) -> Bytes {
50
+ let mut w = BufferWriter::new(env);
51
+ w.write_u16(index).write_u128(gas);
52
+ if let Some(v) = value {
53
+ w.write_u128(v);
54
+ }
55
+ option_header(env, crate::executor_option::EXECUTOR_OPTION_TYPE_LZCOMPOSE, w.to_bytes())
56
+ }
57
+
58
+ pub fn option_ordered_execution(env: &Env) -> Bytes {
59
+ option_header(env, crate::executor_option::EXECUTOR_OPTION_TYPE_ORDERED_EXECUTION, Bytes::new(env))
60
+ }
@@ -14,7 +14,6 @@ soroban-sdk = { workspace = true }
14
14
  # workspace dependencies
15
15
  common-macros = { workspace = true }
16
16
  utils = { workspace = true }
17
- worker = { workspace = true }
18
17
  endpoint-v2 = { workspace = true, features = ["library"] }
19
18
  executor = { workspace = true, features = ["library"] }
20
19
 
@@ -3,3 +3,6 @@
3
3
  mod executor_helper;
4
4
 
5
5
  pub use executor_helper::*;
6
+
7
+ #[cfg(test)]
8
+ mod tests;
@@ -0,0 +1,184 @@
1
+ use super::setup::TestSetup;
2
+ use endpoint_v2::Origin;
3
+ use executor::NativeDropParams;
4
+ use soroban_sdk::{testutils::Address as _, vec, Address, Bytes, BytesN, Vec};
5
+
6
+ // =============================================================================
7
+ // execute() tests
8
+ // =============================================================================
9
+
10
+ #[test]
11
+ fn test_execute_without_value() {
12
+ let setup = TestSetup::new();
13
+ let mut params = setup.default_execution_params();
14
+ assert_eq!(params.value, 0);
15
+ // Verifies that `origin` is forwarded unchanged (merged from the former `test_execute_with_different_origins`).
16
+ params.origin = Origin { src_eid: 999, sender: BytesN::from_array(&setup.env, &[0xABu8; 32]), nonce: 12345 };
17
+
18
+ // Mint tokens to admin to prove transfer is skipped when value == 0
19
+ setup.mint_native(&setup.admin, 100);
20
+ let admin_before = setup.balance_native(&setup.admin);
21
+
22
+ setup.mock_lz_receive_auth(&setup.executor, &params);
23
+
24
+ setup.executor_helper_client.execute(&setup.executor, &params, &setup.admin);
25
+
26
+ // Verify lz_receive was called with correct params
27
+ let record = setup.receiver_client().get_lz_receive();
28
+ assert!(record.is_some());
29
+ let record = record.unwrap();
30
+ assert_eq!(record.executor, setup.executor);
31
+ assert_eq!(record.origin, params.origin);
32
+ assert_eq!(record.origin.src_eid, 999);
33
+ assert_eq!(record.origin.nonce, 12345);
34
+ assert_eq!(record.guid, params.guid);
35
+ assert_eq!(record.message, params.message);
36
+ assert_eq!(record.extra_data, params.extra_data);
37
+ assert_eq!(record.value, params.value);
38
+
39
+ // Verify no token transfer occurred
40
+ assert_eq!(setup.balance_native(&setup.admin), admin_before);
41
+ }
42
+
43
+ #[test]
44
+ fn test_execute_with_large_message() {
45
+ let setup = TestSetup::new();
46
+ let mut params = setup.default_execution_params();
47
+
48
+ // Create a larger message
49
+ let large_data: [u8; 256] = [0xFFu8; 256];
50
+ params.message = Bytes::from_slice(&setup.env, &large_data);
51
+
52
+ setup.mock_lz_receive_auth(&setup.executor, &params);
53
+
54
+ setup.executor_helper_client.execute(&setup.executor, &params, &setup.admin);
55
+
56
+ let record = setup.receiver_client().get_lz_receive();
57
+ assert!(record.is_some());
58
+ assert_eq!(record.unwrap().message.len(), 256);
59
+ }
60
+
61
+ #[test]
62
+ fn test_execute_with_empty_message() {
63
+ let setup = TestSetup::new();
64
+ let mut params = setup.default_execution_params();
65
+ params.message = Bytes::new(&setup.env);
66
+ params.extra_data = Bytes::new(&setup.env);
67
+
68
+ setup.mock_lz_receive_auth(&setup.executor, &params);
69
+
70
+ setup.executor_helper_client.execute(&setup.executor, &params, &setup.admin);
71
+
72
+ let record = setup.receiver_client().get_lz_receive();
73
+ assert!(record.is_some());
74
+ let record = record.unwrap();
75
+ assert_eq!(record.message.len(), 0);
76
+ assert_eq!(record.extra_data.len(), 0);
77
+ }
78
+
79
+ // =============================================================================
80
+ // compose() tests
81
+ // =============================================================================
82
+
83
+ #[test]
84
+ fn test_compose_without_value() {
85
+ let setup = TestSetup::new();
86
+ let params = setup.default_compose_params();
87
+ assert_eq!(params.value, 0);
88
+
89
+ // Mint tokens to admin to prove transfer is skipped when value == 0
90
+ setup.mint_native(&setup.admin, 100);
91
+ let admin_before = setup.balance_native(&setup.admin);
92
+
93
+ setup.mock_lz_compose_auth(&setup.executor, &params);
94
+
95
+ setup.executor_helper_client.compose(&setup.executor, &params, &setup.admin);
96
+
97
+ // Verify lz_compose was called with correct params
98
+ let record = setup.composer_client().get_lz_compose();
99
+ assert!(record.is_some());
100
+ let record = record.unwrap();
101
+ assert_eq!(record.executor, setup.executor);
102
+ assert_eq!(record.from, params.from);
103
+ assert_eq!(record.guid, params.guid);
104
+ assert_eq!(record.index, params.index);
105
+ assert_eq!(record.message, params.message);
106
+ assert_eq!(record.extra_data, params.extra_data);
107
+ assert_eq!(record.value, params.value);
108
+
109
+ // Verify no token transfer occurred
110
+ assert_eq!(setup.balance_native(&setup.admin), admin_before);
111
+ }
112
+
113
+ #[test]
114
+ fn test_compose_with_empty_data() {
115
+ let setup = TestSetup::new();
116
+ let mut params = setup.default_compose_params();
117
+ params.message = Bytes::new(&setup.env);
118
+ params.extra_data = Bytes::new(&setup.env);
119
+
120
+ setup.mock_lz_compose_auth(&setup.executor, &params);
121
+
122
+ setup.executor_helper_client.compose(&setup.executor, &params, &setup.admin);
123
+
124
+ let record = setup.composer_client().get_lz_compose();
125
+ assert!(record.is_some());
126
+ let record = record.unwrap();
127
+ assert_eq!(record.message.len(), 0);
128
+ assert_eq!(record.extra_data.len(), 0);
129
+ }
130
+
131
+ // =============================================================================
132
+ // native_drop() tests
133
+ // =============================================================================
134
+
135
+ #[test]
136
+ fn test_native_drop_delegates_to_executor() {
137
+ let setup = TestSetup::new();
138
+ let origin = setup.default_origin();
139
+ let dst_eid = 2u32;
140
+ let oapp = Address::generate(&setup.env);
141
+
142
+ let receiver1 = Address::generate(&setup.env);
143
+ let receiver2 = Address::generate(&setup.env);
144
+ let params: Vec<NativeDropParams> = vec![
145
+ &setup.env,
146
+ NativeDropParams { receiver: receiver1.clone(), amount: 10 },
147
+ NativeDropParams { receiver: receiver2.clone(), amount: 20 },
148
+ ];
149
+
150
+ setup.mock_native_drop_auth(&setup.executor, &setup.admin, &origin, dst_eid, &oapp, &params);
151
+
152
+ setup.executor_helper_client.native_drop(&setup.executor, &setup.admin, &origin, &dst_eid, &oapp, &params);
153
+
154
+ // Verify native_drop was called on executor with correct params
155
+ let record = setup.executor_client().get_native_drop();
156
+ assert!(record.is_some());
157
+ let record = record.unwrap();
158
+ assert_eq!(record.admin, setup.admin);
159
+ assert_eq!(record.origin, origin);
160
+ assert_eq!(record.dst_eid, dst_eid);
161
+ assert_eq!(record.oapp, oapp);
162
+ assert_eq!(record.params.len(), 2);
163
+ assert_eq!(record.params.get(0).unwrap().receiver, receiver1);
164
+ assert_eq!(record.params.get(0).unwrap().amount, 10);
165
+ assert_eq!(record.params.get(1).unwrap().receiver, receiver2);
166
+ assert_eq!(record.params.get(1).unwrap().amount, 20);
167
+ }
168
+
169
+ #[test]
170
+ fn test_native_drop_with_empty_params() {
171
+ let setup = TestSetup::new();
172
+ let origin = setup.default_origin();
173
+ let dst_eid = 1u32;
174
+ let oapp = Address::generate(&setup.env);
175
+ let params: Vec<NativeDropParams> = vec![&setup.env];
176
+
177
+ setup.mock_native_drop_auth(&setup.executor, &setup.admin, &origin, dst_eid, &oapp, &params);
178
+
179
+ setup.executor_helper_client.native_drop(&setup.executor, &setup.admin, &origin, &dst_eid, &oapp, &params);
180
+
181
+ let record = setup.executor_client().get_native_drop();
182
+ assert!(record.is_some());
183
+ assert_eq!(record.unwrap().params.len(), 0);
184
+ }
@@ -0,0 +1,2 @@
1
+ mod executor_helper;
2
+ mod setup;