@layerzerolabs/protocol-stellar-v2 0.2.8 → 0.2.10

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 (239) hide show
  1. package/.turbo/turbo-build.log +443 -302
  2. package/.turbo/turbo-lint.log +118 -96
  3. package/.turbo/turbo-test.log +853 -731
  4. package/Cargo.lock +120 -37
  5. package/Cargo.toml +8 -5
  6. package/contracts/common-macros/src/contract_impl.rs +44 -0
  7. package/contracts/common-macros/src/lib.rs +86 -40
  8. package/contracts/common-macros/src/ownable.rs +24 -32
  9. package/contracts/common-macros/src/storage.rs +95 -120
  10. package/contracts/common-macros/src/tests/contract_impl.rs +289 -0
  11. package/contracts/common-macros/src/tests/mod.rs +9 -0
  12. package/contracts/common-macros/src/tests/ownable.rs +151 -0
  13. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__contract_impl__snapshot_generated_contract_impl_code.snap +85 -0
  14. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__ownable__snapshot_generated_ownable_code.snap +30 -0
  15. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__ownable__snapshot_only_owner_preserves_function_signature.snap +9 -0
  16. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__storage__snapshot_generated_storage_code.snap +1072 -0
  17. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__ttl_configurable__snapshot_generated_ttl_configurable_code.snap +45 -0
  18. package/contracts/common-macros/src/tests/storage.rs +485 -0
  19. package/contracts/common-macros/src/tests/test_helpers.rs +93 -0
  20. package/contracts/common-macros/src/tests/ttl_configurable.rs +34 -0
  21. package/contracts/common-macros/src/ttl_configurable.rs +31 -14
  22. package/contracts/common-macros/src/utils.rs +27 -0
  23. package/contracts/endpoint-v2/ARCHITECTURE.md +4 -4
  24. package/contracts/endpoint-v2/src/endpoint_v2.rs +18 -15
  25. package/contracts/endpoint-v2/src/interfaces/message_lib.rs +2 -3
  26. package/contracts/endpoint-v2/src/interfaces/message_lib_manager.rs +5 -3
  27. package/contracts/endpoint-v2/src/interfaces/messaging_channel.rs +2 -2
  28. package/contracts/endpoint-v2/src/interfaces/messaging_composer.rs +2 -2
  29. package/contracts/endpoint-v2/src/interfaces/send_lib.rs +4 -4
  30. package/contracts/endpoint-v2/src/lib.rs +6 -5
  31. package/contracts/endpoint-v2/src/message_lib_manager.rs +14 -6
  32. package/contracts/endpoint-v2/src/messaging_channel.rs +6 -2
  33. package/contracts/endpoint-v2/src/messaging_composer.rs +6 -2
  34. package/contracts/endpoint-v2/src/storage.rs +10 -7
  35. package/contracts/endpoint-v2/src/tests/endpoint_v2/pay_messaging_fees.rs +16 -16
  36. package/contracts/endpoint-v2/src/tests/endpoint_v2/ttl_config.rs +46 -46
  37. package/contracts/endpoint-v2/src/tests/mock.rs +2 -2
  38. package/contracts/endpoint-v2/src/util.rs +8 -2
  39. package/contracts/message-libs/block-message-lib/Cargo.toml +1 -0
  40. package/contracts/message-libs/block-message-lib/src/lib.rs +5 -5
  41. package/contracts/message-libs/message-lib-common/src/errors.rs +8 -8
  42. package/contracts/message-libs/message-lib-common/src/interfaces/dvn.rs +0 -1
  43. package/contracts/message-libs/message-lib-common/src/interfaces/mod.rs +3 -3
  44. package/contracts/message-libs/message-lib-common/src/lib.rs +0 -2
  45. package/contracts/message-libs/message-lib-common/src/packet_codec_v1.rs +4 -6
  46. package/contracts/message-libs/message-lib-common/src/tests/packet_codec_v1.rs +2 -2
  47. package/contracts/message-libs/message-lib-common/src/tests/worker_options.rs +11 -11
  48. package/contracts/message-libs/message-lib-common/src/worker_options.rs +10 -16
  49. package/contracts/message-libs/simple-message-lib/src/errors.rs +0 -4
  50. package/contracts/message-libs/simple-message-lib/src/simple_message_lib.rs +49 -34
  51. package/contracts/message-libs/simple-message-lib/src/storage.rs +3 -7
  52. package/contracts/message-libs/simple-message-lib/src/test.rs +3 -3
  53. package/contracts/message-libs/treasury/src/storage.rs +1 -2
  54. package/contracts/message-libs/treasury/src/tests/setup.rs +3 -2
  55. package/contracts/message-libs/treasury/src/tests/treasury_tests.rs +0 -13
  56. package/contracts/message-libs/treasury/src/treasury.rs +18 -21
  57. package/contracts/message-libs/uln-302/Cargo.toml +1 -0
  58. package/contracts/message-libs/uln-302/src/interfaces/mod.rs +4 -4
  59. package/contracts/message-libs/uln-302/src/interfaces/{receive.rs → receive_uln.rs} +3 -3
  60. package/contracts/message-libs/uln-302/src/interfaces/{send.rs → send_uln.rs} +8 -80
  61. package/contracts/message-libs/uln-302/src/lib.rs +5 -4
  62. package/contracts/message-libs/uln-302/src/{receive.rs → receive_uln.rs} +20 -12
  63. package/contracts/message-libs/uln-302/src/{send.rs → send_uln.rs} +19 -13
  64. package/contracts/message-libs/uln-302/src/storage.rs +1 -2
  65. package/contracts/message-libs/uln-302/src/tests/config/uln_config.rs +3 -2
  66. package/contracts/message-libs/uln-302/src/tests/send_uln302/send.rs +30 -30
  67. package/contracts/message-libs/uln-302/src/tests/setup.rs +12 -11
  68. package/contracts/message-libs/uln-302/src/tests/uln302/set_config.rs +1 -1
  69. package/contracts/message-libs/uln-302/src/{config_validation.rs → types.rs} +79 -11
  70. package/contracts/message-libs/uln-302/src/uln302.rs +15 -10
  71. package/contracts/oapp-macros/Cargo.toml +2 -8
  72. package/contracts/oapp-macros/src/lib.rs +57 -311
  73. package/contracts/oapp-macros/src/oapp_core.rs +23 -32
  74. package/contracts/oapp-macros/src/oapp_full.rs +8 -2
  75. package/contracts/oapp-macros/src/oapp_options_type3.rs +21 -36
  76. package/contracts/oapp-macros/src/oapp_receiver.rs +38 -57
  77. package/contracts/oapp-macros/src/oapp_sender.rs +12 -14
  78. package/contracts/oapp-macros/src/util.rs +14 -10
  79. package/contracts/oapps/counter/Cargo.toml +2 -1
  80. package/contracts/oapps/counter/integration_tests/utils.rs +4 -4
  81. package/contracts/oapps/counter/src/codec.rs +8 -9
  82. package/contracts/oapps/counter/src/counter.rs +156 -147
  83. package/contracts/oapps/counter/src/storage.rs +1 -2
  84. package/contracts/oapps/counter/src/tests/test_codec.rs +5 -5
  85. package/contracts/oapps/counter/src/tests/test_counter.rs +11 -13
  86. package/contracts/oapps/oapp/Cargo.toml +1 -0
  87. package/contracts/oapps/oapp/src/errors.rs +1 -1
  88. package/contracts/oapps/oapp/src/lib.rs +3 -0
  89. package/contracts/oapps/oapp/src/macro_tests/mod.rs +1 -0
  90. package/contracts/oapps/oapp/src/macro_tests/test_macros.rs +312 -0
  91. package/contracts/oapps/oapp/src/oapp_core.rs +52 -53
  92. package/contracts/oapps/oapp/src/oapp_options_type3.rs +18 -28
  93. package/contracts/oapps/oapp/src/oapp_receiver.rs +82 -31
  94. package/contracts/oapps/oapp/src/oapp_sender.rs +55 -13
  95. package/contracts/oapps/oapp/src/tests/test_oapp_core.rs +16 -3
  96. package/contracts/oapps/oapp/src/tests/test_oapp_options_type3.rs +33 -8
  97. package/contracts/oapps/oapp/src/tests/test_oapp_receiver.rs +6 -9
  98. package/contracts/oapps/oapp/src/tests/test_oapp_sender.rs +28 -15
  99. package/contracts/oapps/oft/Cargo.toml +27 -0
  100. package/contracts/oapps/oft/integration-tests/mod.rs +3 -0
  101. package/contracts/oapps/oft/integration-tests/setup.rs +320 -0
  102. package/contracts/oapps/oft/integration-tests/test_with_sml.rs +155 -0
  103. package/contracts/oapps/oft/integration-tests/utils.rs +201 -0
  104. package/contracts/oapps/oft/src/codec/mod.rs +2 -0
  105. package/contracts/oapps/oft/src/codec/oft_compose_msg_codec.rs +55 -0
  106. package/contracts/oapps/oft/src/codec/oft_msg_codec.rs +62 -0
  107. package/contracts/oapps/oft/src/constants.rs +5 -0
  108. package/contracts/oapps/oft/src/errors.rs +8 -0
  109. package/contracts/oapps/oft/src/events.rs +19 -0
  110. package/contracts/oapps/oft/src/interfaces/mint_burn_token.rs +23 -0
  111. package/contracts/oapps/oft/src/interfaces/mod.rs +3 -0
  112. package/contracts/oapps/oft/src/lib.rs +22 -0
  113. package/contracts/oapps/oft/src/macro_tests/mod.rs +2 -0
  114. package/contracts/oapps/oft/src/macro_tests/test_all_default.rs +41 -0
  115. package/contracts/oapps/oft/src/macro_tests/test_override.rs +83 -0
  116. package/contracts/oapps/oft/src/oft.rs +320 -0
  117. package/contracts/oapps/oft/src/oft_types/lock_unlock.rs +50 -0
  118. package/contracts/oapps/oft/src/oft_types/mint_burn.rs +50 -0
  119. package/contracts/oapps/oft/src/oft_types/mod.rs +10 -0
  120. package/contracts/oapps/oft/src/storage.rs +11 -0
  121. package/contracts/oapps/oft/src/tests/mod.rs +13 -0
  122. package/contracts/oapps/oft/src/tests/test_decimals.rs +89 -0
  123. package/contracts/oapps/oft/src/tests/test_lz_receive.rs +282 -0
  124. package/contracts/oapps/oft/src/tests/test_oft_compose_msg_codec.rs +68 -0
  125. package/contracts/oapps/oft/src/tests/test_oft_msg_codec.rs +136 -0
  126. package/contracts/oapps/oft/src/tests/test_oft_version.rs +13 -0
  127. package/contracts/oapps/oft/src/tests/test_quote_oft.rs +159 -0
  128. package/contracts/oapps/oft/src/tests/test_quote_send.rs +195 -0
  129. package/contracts/oapps/oft/src/tests/test_resolve_address.rs +37 -0
  130. package/contracts/oapps/oft/src/tests/test_send.rs +915 -0
  131. package/contracts/oapps/oft/src/tests/test_token.rs +47 -0
  132. package/contracts/oapps/oft/src/tests/test_utils.rs +789 -0
  133. package/contracts/oapps/oft/src/types.rs +38 -0
  134. package/contracts/oapps/oft/src/utils.rs +67 -0
  135. package/contracts/oapps/oft-mint-burn/Cargo.toml +26 -0
  136. package/contracts/oapps/oft-mint-burn/src/lib.rs +3 -0
  137. package/contracts/oapps/oft-mint-burn/src/oft.rs +28 -0
  138. package/contracts/oapps/oft-mint-burn/src/tests/mod.rs +1 -0
  139. package/contracts/utils/src/buffer_reader.rs +8 -9
  140. package/contracts/utils/src/buffer_writer.rs +11 -5
  141. package/contracts/utils/src/errors.rs +5 -5
  142. package/contracts/utils/src/ownable.rs +14 -6
  143. package/contracts/utils/src/testing_utils.rs +11 -1
  144. package/contracts/utils/src/tests/buffer_reader.rs +491 -730
  145. package/contracts/utils/src/tests/buffer_writer.rs +336 -148
  146. package/contracts/utils/src/tests/bytes_ext.rs +125 -40
  147. package/contracts/utils/src/tests/mod.rs +3 -0
  148. package/contracts/utils/src/tests/ownable.rs +379 -27
  149. package/contracts/utils/src/tests/test_helper.rs +47 -0
  150. package/contracts/utils/src/tests/testing_utils.rs +555 -0
  151. package/contracts/utils/src/tests/ttl.rs +421 -0
  152. package/contracts/utils/src/ttl.rs +29 -89
  153. package/contracts/workers/dvn/Cargo.toml +31 -0
  154. package/contracts/workers/dvn/src/auth.rs +66 -0
  155. package/contracts/workers/dvn/src/dvn.rs +143 -0
  156. package/contracts/workers/dvn/src/errors.rs +21 -0
  157. package/contracts/workers/dvn/src/events.rs +19 -0
  158. package/contracts/workers/dvn/src/interfaces/dvn.rs +12 -0
  159. package/contracts/workers/dvn/src/interfaces/mod.rs +5 -0
  160. package/contracts/workers/dvn/src/interfaces/multisig.rs +15 -0
  161. package/contracts/workers/dvn/src/lib.rs +24 -0
  162. package/contracts/workers/dvn/src/multisig.rs +127 -0
  163. package/contracts/workers/dvn/src/storage.rs +35 -0
  164. package/contracts/workers/dvn/src/tests/auth.rs +237 -0
  165. package/contracts/workers/dvn/src/tests/dvn.rs +349 -0
  166. package/contracts/workers/dvn/src/tests/key_pair.rs +66 -0
  167. package/contracts/workers/dvn/src/tests/mod.rs +5 -0
  168. package/contracts/workers/dvn/src/tests/multisig/mod.rs +3 -0
  169. package/contracts/workers/dvn/src/tests/multisig/set_signer.rs +133 -0
  170. package/contracts/workers/dvn/src/tests/multisig/set_threshold.rs +108 -0
  171. package/contracts/workers/dvn/src/tests/multisig/verify_signatures.rs +109 -0
  172. package/contracts/workers/dvn/src/tests/setup.rs +109 -0
  173. package/contracts/workers/dvn/src/types.rs +26 -0
  174. package/contracts/workers/dvn-fee-lib/Cargo.toml +24 -0
  175. package/contracts/workers/dvn-fee-lib/src/dvn_fee_lib.rs +113 -0
  176. package/contracts/workers/dvn-fee-lib/src/errors.rs +8 -0
  177. package/contracts/workers/dvn-fee-lib/src/lib.rs +17 -0
  178. package/contracts/workers/dvn-fee-lib/src/tests/dvn_fee_lib.rs +282 -0
  179. package/contracts/workers/dvn-fee-lib/src/tests/mod.rs +1 -0
  180. package/contracts/workers/executor/Cargo.toml +10 -7
  181. package/contracts/workers/executor/src/errors.rs +8 -0
  182. package/contracts/workers/executor/src/events.rs +4 -7
  183. package/contracts/workers/executor/src/interfaces/executor.rs +72 -22
  184. package/contracts/workers/executor/src/interfaces/mod.rs +0 -2
  185. package/contracts/workers/executor/src/lib.rs +16 -7
  186. package/contracts/workers/executor/src/lz_executor.rs +308 -0
  187. package/contracts/workers/executor/src/storage.rs +24 -16
  188. package/contracts/workers/executor-fee-lib/Cargo.toml +22 -0
  189. package/contracts/workers/executor-fee-lib/src/errors.rs +15 -0
  190. package/contracts/workers/executor-fee-lib/src/executor_fee_lib.rs +215 -0
  191. package/contracts/workers/executor-fee-lib/src/executor_option.rs +203 -0
  192. package/contracts/workers/executor-fee-lib/src/lib.rs +7 -0
  193. package/contracts/workers/executor-helper/Cargo.toml +29 -0
  194. package/contracts/workers/executor-helper/src/executor_helper.rs +161 -0
  195. package/contracts/workers/executor-helper/src/lib.rs +11 -0
  196. package/contracts/workers/{worker-common → worker}/Cargo.toml +1 -4
  197. package/contracts/workers/worker/src/errors.rs +24 -0
  198. package/contracts/workers/worker/src/events.rs +62 -0
  199. package/contracts/workers/worker/src/interfaces/dvn_fee_lib.rs +75 -0
  200. package/contracts/workers/worker/src/interfaces/executor_fee_lib.rs +84 -0
  201. package/contracts/workers/{worker-common → worker}/src/interfaces/mod.rs +2 -2
  202. package/contracts/workers/worker/src/interfaces/price_feed.rs +85 -0
  203. package/contracts/workers/worker/src/lib.rs +14 -0
  204. package/contracts/workers/worker/src/storage.rs +63 -0
  205. package/contracts/workers/worker/src/worker.rs +459 -0
  206. package/package.json +3 -3
  207. package/sdk/dist/generated/bml.d.ts +88 -17
  208. package/sdk/dist/generated/bml.js +62 -16
  209. package/sdk/dist/generated/counter.d.ts +281 -102
  210. package/sdk/dist/generated/counter.js +93 -41
  211. package/sdk/dist/generated/endpoint.d.ts +128 -105
  212. package/sdk/dist/generated/endpoint.js +47 -45
  213. package/sdk/dist/generated/sml.d.ts +212 -69
  214. package/sdk/dist/generated/sml.js +103 -53
  215. package/sdk/dist/generated/uln302.d.ts +270 -173
  216. package/sdk/dist/generated/uln302.js +112 -64
  217. package/sdk/package.json +11 -11
  218. package/sdk/test/index.test.ts +147 -42
  219. package/sdk/test/suites/constants.ts +7 -3
  220. package/sdk/test/suites/deploy.ts +65 -42
  221. package/sdk/test/suites/localnet.ts +2 -2
  222. package/sdk/test/suites/scan.ts +28 -25
  223. package/sdk/test/utils.ts +199 -0
  224. package/sdk/tsconfig.json +93 -95
  225. package/tools/ts-bindings-gen/src/main.rs +2 -0
  226. package/contracts/common-macros/src/snapshots/common_macros__tests__tests__snapshot_generated_storage_code.snap +0 -310
  227. package/contracts/common-macros/src/tests.rs +0 -287
  228. package/contracts/oapp-macros/tests/test_macros.rs +0 -522
  229. package/contracts/workers/executor/src/executor.rs +0 -347
  230. package/contracts/workers/executor/src/interfaces/types.rs +0 -51
  231. package/contracts/workers/worker-common/src/constants.rs +0 -17
  232. package/contracts/workers/worker-common/src/errors.rs +0 -6
  233. package/contracts/workers/worker-common/src/events.rs +0 -34
  234. package/contracts/workers/worker-common/src/interfaces/executor_fee_lib.rs +0 -35
  235. package/contracts/workers/worker-common/src/interfaces/price_feed.rs +0 -40
  236. package/contracts/workers/worker-common/src/interfaces/worker.rs +0 -60
  237. package/contracts/workers/worker-common/src/lib.rs +0 -19
  238. package/contracts/workers/worker-common/src/storage.rs +0 -32
  239. package/contracts/workers/worker-common/src/worker_common.rs +0 -166
@@ -2,1005 +2,766 @@ use soroban_sdk::{address_payload::AddressPayload, testutils::Address as _, Addr
2
2
 
3
3
  use crate::buffer_reader::BufferReader;
4
4
  use crate::buffer_writer::BufferWriter;
5
+ use crate::bytes_ext::BytesExt;
5
6
 
6
- #[test]
7
- fn test_new_buffer_reader() {
8
- let env = Env::default();
9
- let bytes = Bytes::from_array(&env, &[0u8, 1, 2, 3, 4, 5]);
10
- let _reader = BufferReader::new(&bytes);
11
-
12
- // Verify reader is created (we can't access pos directly but can verify by reading)
13
- assert!(true); // Successfully created
14
- }
15
-
16
- #[test]
17
- fn test_read_u32() {
18
- let env = Env::default();
19
- // Create bytes representing u32 value 0x01020304 (16909060 in decimal)
20
- let bytes = Bytes::from_array(&env, &[0x01, 0x02, 0x03, 0x04]);
21
- let mut reader = BufferReader::new(&bytes);
22
-
23
- let value = reader.read_u32();
24
- assert_eq!(value, 0x01020304u32);
25
- }
26
-
27
- #[test]
28
- fn test_read_u32_zero() {
29
- let env = Env::default();
30
- let bytes = Bytes::from_array(&env, &[0x00, 0x00, 0x00, 0x00]);
31
- let mut reader = BufferReader::new(&bytes);
32
-
33
- let value = reader.read_u32();
34
- assert_eq!(value, 0u32);
35
- }
36
-
37
- #[test]
38
- fn test_read_u32_max_value() {
39
- let env = Env::default();
40
- let bytes = Bytes::from_array(&env, &[0xFF, 0xFF, 0xFF, 0xFF]);
41
- let mut reader = BufferReader::new(&bytes);
42
-
43
- let value = reader.read_u32();
44
- assert_eq!(value, u32::MAX);
45
- }
46
-
47
- #[test]
48
- fn test_read_u64() {
49
- let env = Env::default();
50
- // Create bytes representing u64 value 0x0102030405060708
51
- let bytes = Bytes::from_array(&env, &[0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]);
52
- let mut reader = BufferReader::new(&bytes);
7
+ use crate::tests::test_helper::{assert_address_payload_matches, assert_panics_contains};
53
8
 
54
- let value = reader.read_u64();
55
- assert_eq!(value, 0x0102030405060708u64);
56
- }
9
+ type ReaderStep = fn(&mut BufferReader);
57
10
 
58
- #[test]
59
- fn test_read_u64_zero() {
60
- let env = Env::default();
61
- let bytes = Bytes::from_array(&env, &[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
62
- let mut reader = BufferReader::new(&bytes);
63
-
64
- let value = reader.read_u64();
65
- assert_eq!(value, 0u64);
11
+ fn assert_reader_panics_contains(case: &str, raw: &[u8], step: ReaderStep, expected_substring: &str) {
12
+ assert_panics_contains(case, expected_substring, || {
13
+ let env = Env::default();
14
+ let bytes = Bytes::from_slice(&env, raw);
15
+ let mut reader = BufferReader::new(&bytes);
16
+ step(&mut reader);
17
+ });
66
18
  }
67
19
 
68
- #[test]
69
- fn test_read_u64_max_value() {
70
- let env = Env::default();
71
- let bytes = Bytes::from_array(&env, &[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]);
20
+ /// Helper to test U256 read roundtrip
21
+ fn test_u256_read_roundtrip(env: &Env, value: &soroban_sdk::U256) {
22
+ let mut writer = BufferWriter::new(env);
23
+ writer.write_u256(value.clone());
24
+ let bytes = writer.to_bytes();
72
25
  let mut reader = BufferReader::new(&bytes);
73
-
74
- let value = reader.read_u64();
75
- assert_eq!(value, u64::MAX);
26
+ assert_eq!(reader.read_u256(), *value);
27
+ assert_eq!(reader.remaining_len(), 0);
76
28
  }
77
29
 
78
- #[test]
79
- fn test_sequential_reads() {
80
- let env = Env::default();
81
-
82
- // Create a buffer with multiple values:
83
- // - u32: 0x01020304
84
- // - u64: 0x0102030405060708
85
- // - another u32: 0xAABBCCDD
86
- let buffer_array: [u8; 16] = [
87
- 0x01, 0x02, 0x03, 0x04, // u32
88
- 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // u64
89
- 0xAA, 0xBB, 0xCC, 0xDD, // u32
90
- ];
30
+ /// Helper to test address roundtrip
31
+ fn test_address_roundtrip(env: &Env, address: &Address) {
32
+ let mut writer = BufferWriter::new(env);
33
+ writer.write_address(address);
34
+ let bytes = writer.to_bytes();
91
35
 
92
- let bytes = Bytes::from_array(&env, &buffer_array);
93
36
  let mut reader = BufferReader::new(&bytes);
37
+ let read_address = reader.read_address();
94
38
 
95
- // Read in sequence and verify position is being tracked correctly
96
- let val1 = reader.read_u32();
97
- assert_eq!(val1, 0x01020304u32);
98
-
99
- let val2 = reader.read_u64();
100
- assert_eq!(val2, 0x0102030405060708u64);
101
-
102
- let val3 = reader.read_u32();
103
- assert_eq!(val3, 0xAABBCCDDu32);
39
+ assert_eq!(read_address, *address);
40
+ assert_eq!(reader.remaining_len(), 0);
104
41
  }
105
42
 
106
- #[test]
107
- fn test_read_multiple_u32() {
108
- let env = Env::default();
109
- let bytes = Bytes::from_array(
110
- &env,
111
- &[
112
- 0x00, 0x00, 0x00, 0x01, // 1
113
- 0x00, 0x00, 0x00, 0x02, // 2
114
- 0x00, 0x00, 0x00, 0x03, // 3
115
- ],
116
- );
117
- let mut reader = BufferReader::new(&bytes);
118
-
119
- assert_eq!(reader.read_u32(), 1u32);
120
- assert_eq!(reader.read_u32(), 2u32);
121
- assert_eq!(reader.read_u32(), 3u32);
122
- }
43
+ // ============================================
44
+ // read_primitives tests (u8, u16, u32, u64, u128, u256, bool)
45
+ // ============================================
123
46
 
124
47
  #[test]
125
- fn test_read_multiple_u64() {
48
+ fn test_read_primitives_big_endian_golden_bytes() {
126
49
  let env = Env::default();
127
50
  let bytes = Bytes::from_array(
128
51
  &env,
129
52
  &[
130
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // 1
131
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, // 2
53
+ 0x12, // u8
54
+ 0x34, 0x56, // u16
55
+ 0x78, 0x9A, 0xBC, 0xDE, // u32
56
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // u64
57
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
58
+ 0x10, // u128
132
59
  ],
133
60
  );
134
61
  let mut reader = BufferReader::new(&bytes);
135
62
 
136
- assert_eq!(reader.read_u64(), 1u64);
137
- assert_eq!(reader.read_u64(), 2u64);
138
- }
139
-
140
- #[test]
141
- #[should_panic]
142
- fn test_read_u32_insufficient_bytes_empty() {
143
- let env = Env::default();
144
- let bytes = Bytes::from_array(&env, &[]);
145
- let mut reader = BufferReader::new(&bytes);
146
-
147
- // Should panic - no bytes available
148
- reader.read_u32();
63
+ assert_eq!(reader.read_u8(), 0x12);
64
+ assert_eq!(reader.read_u16(), 0x3456);
65
+ assert_eq!(reader.read_u32(), 0x789ABCDE);
66
+ assert_eq!(reader.read_u64(), 0x0102030405060708);
67
+ assert_eq!(reader.read_u128(), 0x0102030405060708090a0b0c0d0e0f10);
68
+ assert_eq!(reader.remaining_len(), 0);
149
69
  }
150
70
 
151
71
  #[test]
152
- #[should_panic]
153
- fn test_read_u32_insufficient_bytes_partial() {
72
+ fn test_read_primitives_roundtrip() {
154
73
  let env = Env::default();
155
- // Only 3 bytes, need 4 for u32
156
- let bytes = Bytes::from_array(&env, &[0x01, 0x02, 0x03]);
157
- let mut reader = BufferReader::new(&bytes);
158
-
159
- // Should panic - not enough bytes
160
- reader.read_u32();
161
- }
74
+ let mut writer = BufferWriter::new(&env);
75
+ writer
76
+ .write_u8(0x12)
77
+ .write_u16(0x3456)
78
+ .write_u32(0x789ABCDE)
79
+ .write_u64(0x0102030405060708)
80
+ .write_u128(0x0102030405060708090a0b0c0d0e0f10);
162
81
 
163
- #[test]
164
- #[should_panic]
165
- fn test_read_u32_insufficient_bytes_one() {
166
- let env = Env::default();
167
- // Only 1 byte, need 4 for u32
168
- let bytes = Bytes::from_array(&env, &[0x01]);
82
+ let bytes = writer.to_bytes();
169
83
  let mut reader = BufferReader::new(&bytes);
170
84
 
171
- // Should panic - not enough bytes
172
- reader.read_u32();
85
+ assert_eq!(reader.read_u8(), 0x12);
86
+ assert_eq!(reader.read_u16(), 0x3456);
87
+ assert_eq!(reader.read_u32(), 0x789ABCDE);
88
+ assert_eq!(reader.read_u64(), 0x0102030405060708);
89
+ assert_eq!(reader.read_u128(), 0x0102030405060708090a0b0c0d0e0f10);
90
+ assert_eq!(reader.remaining_len(), 0);
173
91
  }
174
92
 
175
93
  #[test]
176
- #[should_panic]
177
- fn test_read_u64_insufficient_bytes_empty() {
94
+ fn test_read_boundary_values() {
178
95
  let env = Env::default();
179
- let bytes = Bytes::from_array(&env, &[]);
180
- let mut reader = BufferReader::new(&bytes);
96
+ let mut writer = BufferWriter::new(&env);
181
97
 
182
- // Should panic - no bytes available
183
- reader.read_u64();
184
- }
98
+ // Write boundary values for each type
99
+ writer
100
+ .write_u8(0)
101
+ .write_u8(u8::MAX)
102
+ .write_u16(0)
103
+ .write_u16(u16::MAX)
104
+ .write_u32(0)
105
+ .write_u32(u32::MAX)
106
+ .write_u64(0)
107
+ .write_u64(u64::MAX)
108
+ .write_u128(0)
109
+ .write_u128(u128::MAX);
185
110
 
186
- #[test]
187
- #[should_panic]
188
- fn test_read_u64_insufficient_bytes_partial() {
189
- let env = Env::default();
190
- // Only 7 bytes, need 8 for u64
191
- let bytes = Bytes::from_array(&env, &[0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07]);
111
+ let bytes = writer.to_bytes();
192
112
  let mut reader = BufferReader::new(&bytes);
193
113
 
194
- // Should panic - not enough bytes
195
- reader.read_u64();
114
+ assert_eq!(reader.read_u8(), 0);
115
+ assert_eq!(reader.read_u8(), u8::MAX);
116
+ assert_eq!(reader.read_u16(), 0);
117
+ assert_eq!(reader.read_u16(), u16::MAX);
118
+ assert_eq!(reader.read_u32(), 0);
119
+ assert_eq!(reader.read_u32(), u32::MAX);
120
+ assert_eq!(reader.read_u64(), 0);
121
+ assert_eq!(reader.read_u64(), u64::MAX);
122
+ assert_eq!(reader.read_u128(), 0);
123
+ assert_eq!(reader.read_u128(), u128::MAX);
196
124
  }
197
125
 
198
126
  #[test]
199
- #[should_panic]
200
- fn test_read_u64_insufficient_bytes_only_four() {
127
+ fn test_read_bool() {
201
128
  let env = Env::default();
202
- // Only 4 bytes, need 8 for u64
203
- let bytes = Bytes::from_array(&env, &[0x01, 0x02, 0x03, 0x04]);
129
+ let bytes = Bytes::from_array(&env, &[0x00, 0x01, 0x02, 0x7F, 0x80, 0xFF]);
204
130
  let mut reader = BufferReader::new(&bytes);
205
131
 
206
- // Should panic - not enough bytes
207
- reader.read_u64();
132
+ assert!(!reader.read_bool()); // 0x00 -> false
133
+ assert!(reader.read_bool()); // 0x01 -> true
134
+ assert!(reader.read_bool()); // 0x02 -> true (any non-zero is true)
135
+ assert!(reader.read_bool()); // 0x7F -> true
136
+ assert!(reader.read_bool()); // 0x80 -> true
137
+ assert!(reader.read_bool()); // 0xFF -> true
138
+ assert_eq!(reader.remaining_len(), 0);
208
139
  }
209
140
 
210
141
  #[test]
211
- #[should_panic]
212
- fn test_sequential_reads_run_out_of_bytes() {
142
+ fn test_read_u256_boundary_values() {
143
+ use soroban_sdk::U256;
213
144
  let env = Env::default();
214
145
 
215
- // Only enough for u32 and partial u64
216
- let buffer_array: [u8; 10] = [
217
- 0x01, 0x02, 0x03, 0x04, // u32 (4 bytes)
218
- 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // partial u64 (only 6 bytes, need 8)
219
- ];
220
-
221
- let bytes = Bytes::from_array(&env, &buffer_array);
222
- let mut reader = BufferReader::new(&bytes);
146
+ // Zero
147
+ let zero = U256::from_u32(&env, 0);
148
+ test_u256_read_roundtrip(&env, &zero);
223
149
 
224
- // First read succeeds
225
- let _val1 = reader.read_u32();
150
+ // From u128::MAX
151
+ let from_u128_max = U256::from_u128(&env, u128::MAX);
152
+ test_u256_read_roundtrip(&env, &from_u128_max);
226
153
 
227
- // Second read should panic - not enough bytes for u64
228
- reader.read_u64();
154
+ // Max (all 0xFF bytes)
155
+ let max_bytes = Bytes::from_array(&env, &[0xFF; 32]);
156
+ let max_u256 = U256::from_be_bytes(&env, &max_bytes);
157
+ test_u256_read_roundtrip(&env, &max_u256);
229
158
  }
230
159
 
231
- #[test]
232
- #[should_panic]
233
- fn test_read_after_buffer_exhausted() {
234
- let env = Env::default();
235
- // Exactly 4 bytes
236
- let bytes = Bytes::from_array(&env, &[0x01, 0x02, 0x03, 0x04]);
237
- let mut reader = BufferReader::new(&bytes);
238
-
239
- // First read succeeds and exhausts the buffer
240
- let _val = reader.read_u32();
241
-
242
- // Second read should panic - no bytes left
243
- reader.read_u32();
244
- }
160
+ // ============================================
161
+ // read_bytes tests (read_bytes, read_bytes_n)
162
+ // ============================================
245
163
 
246
- // Tests for read() method
247
164
  #[test]
248
- fn test_read() {
165
+ fn test_read_bytes_operations() {
249
166
  let env = Env::default();
250
167
  let bytes = Bytes::from_array(&env, &[0x01, 0x02, 0x03, 0x04, 0x05, 0x06]);
251
168
  let mut reader = BufferReader::new(&bytes);
252
169
 
170
+ // Read partial
253
171
  let chunk1 = reader.read_bytes(3);
254
172
  assert_eq!(chunk1.len(), 3);
255
173
  assert_eq!(chunk1.get(0).unwrap(), 0x01);
256
- assert_eq!(chunk1.get(1).unwrap(), 0x02);
257
174
  assert_eq!(chunk1.get(2).unwrap(), 0x03);
258
175
 
259
- let chunk2 = reader.read_bytes(2);
260
- assert_eq!(chunk2.len(), 2);
176
+ // Read remaining
177
+ let chunk2 = reader.read_bytes_until_end();
178
+ assert_eq!(chunk2.len(), 3);
261
179
  assert_eq!(chunk2.get(0).unwrap(), 0x04);
262
- assert_eq!(chunk2.get(1).unwrap(), 0x05);
263
- }
264
-
265
- #[test]
266
- fn test_read_single_byte() {
267
- let env = Env::default();
268
- let bytes = Bytes::from_array(&env, &[0xAB]);
269
- let mut reader = BufferReader::new(&bytes);
270
-
271
- let chunk = reader.read_bytes(1);
272
- assert_eq!(chunk.len(), 1);
273
- assert_eq!(chunk.get(0).unwrap(), 0xAB);
180
+ assert_eq!(chunk2.get(2).unwrap(), 0x06);
181
+ assert_eq!(reader.remaining_len(), 0);
274
182
  }
275
183
 
276
184
  #[test]
277
- fn test_read_entire_buffer() {
185
+ fn test_read_bytes_n() {
278
186
  let env = Env::default();
279
- let bytes = Bytes::from_array(&env, &[0x01, 0x02, 0x03, 0x04]);
187
+ let bytes = Bytes::from_array(
188
+ &env,
189
+ &[
190
+ 0x01, 0x02, 0x03, 0x04, // 4 bytes
191
+ 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, // 8 bytes
192
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21,
193
+ 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, // 32 bytes
194
+ ],
195
+ );
280
196
  let mut reader = BufferReader::new(&bytes);
281
197
 
282
- let chunk = reader.read_bytes(4);
283
- assert_eq!(chunk.len(), 4);
284
- assert_eq!(chunk.get(0).unwrap(), 0x01);
285
- assert_eq!(chunk.get(3).unwrap(), 0x04);
286
- }
287
-
288
- // Tests for rewind() method
289
- #[test]
290
- fn test_rewind() {
291
- let env = Env::default();
292
- let bytes = Bytes::from_array(&env, &[0x01, 0x02, 0x03, 0x04, 0x05, 0x06]);
293
- let mut reader = BufferReader::new(&bytes);
198
+ let val4: BytesN<4> = reader.read_bytes_n();
199
+ assert_eq!(val4, BytesN::<4>::from_array(&env, &[0x01, 0x02, 0x03, 0x04]));
294
200
 
295
- // Read 4 bytes
296
- let _chunk1 = reader.read_bytes(4);
201
+ let val8: BytesN<8> = reader.read_bytes_n();
202
+ assert_eq!(val8, BytesN::<8>::from_array(&env, &[0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c]));
297
203
 
298
- // Rewind 2 bytes
299
- reader.rewind(2);
204
+ let val32: BytesN<32> = reader.read_bytes_n();
205
+ assert_eq!(
206
+ val32,
207
+ BytesN::<32>::from_array(
208
+ &env,
209
+ &[
210
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
211
+ 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f
212
+ ]
213
+ )
214
+ );
300
215
 
301
- // Read again should get bytes starting from position 2
302
- let chunk2 = reader.read_bytes(2);
303
- assert_eq!(chunk2.get(0).unwrap(), 0x03);
304
- assert_eq!(chunk2.get(1).unwrap(), 0x04);
216
+ assert_eq!(reader.remaining_len(), 0);
305
217
  }
306
218
 
307
219
  #[test]
308
- fn test_rewind_chaining() {
220
+ fn test_read_bytes_zero_length() {
309
221
  let env = Env::default();
310
222
  let bytes = Bytes::from_array(&env, &[0x01, 0x02, 0x03, 0x04]);
311
223
  let mut reader = BufferReader::new(&bytes);
312
224
 
313
- reader.read_bytes(4);
314
- // Test that rewind returns &mut Self for chaining
315
- let chunk = reader.rewind(2).read_bytes(1);
316
- assert_eq!(chunk.get(0).unwrap(), 0x03);
317
- }
318
-
319
- #[test]
320
- fn test_rewind_to_start() {
321
- let env = Env::default();
322
- let bytes = Bytes::from_array(&env, &[0xAA, 0xBB, 0xCC]);
323
- let mut reader = BufferReader::new(&bytes);
324
-
325
- reader.read_bytes(3);
326
- reader.rewind(3);
225
+ // Read zero bytes should return empty bytes and not advance position
226
+ let chunk = reader.read_bytes(0);
227
+ assert_eq!(chunk.len(), 0);
228
+ assert_eq!(reader.position(), 0);
327
229
 
328
- let chunk = reader.read_bytes(1);
329
- assert_eq!(chunk.get(0).unwrap(), 0xAA);
230
+ // Should be able to read normally after zero-length read
231
+ assert_eq!(reader.read_u8(), 0x01);
330
232
  }
331
233
 
332
- // Tests for read_u8() method
333
- #[test]
334
- fn test_read_u8() {
335
- let env = Env::default();
336
- let bytes = Bytes::from_array(&env, &[0x42]);
337
- let mut reader = BufferReader::new(&bytes);
338
-
339
- let value = reader.read_u8();
340
- assert_eq!(value, 0x42);
341
- }
234
+ // ============================================
235
+ // read_bytes_until_end tests
236
+ // ============================================
342
237
 
343
238
  #[test]
344
- fn test_read_u8_zero() {
239
+ fn test_read_bytes_until_end_at_start() {
345
240
  let env = Env::default();
346
- let bytes = Bytes::from_array(&env, &[0x00]);
241
+ let bytes = Bytes::from_array(&env, &[0x01, 0x02, 0x03, 0x04]);
347
242
  let mut reader = BufferReader::new(&bytes);
348
243
 
349
- let value = reader.read_u8();
350
- assert_eq!(value, 0u8);
244
+ let all_bytes = reader.read_bytes_until_end();
245
+ assert_eq!(all_bytes.len(), 4);
246
+ assert_eq!(all_bytes.get(0).unwrap(), 0x01);
247
+ assert_eq!(all_bytes.get(3).unwrap(), 0x04);
248
+ assert_eq!(reader.remaining_len(), 0);
249
+ assert_eq!(reader.position(), 4);
351
250
  }
352
251
 
353
252
  #[test]
354
- fn test_read_u8_max_value() {
253
+ fn test_read_bytes_until_end_after_partial_read() {
355
254
  let env = Env::default();
356
- let bytes = Bytes::from_array(&env, &[0xFF]);
255
+ let bytes = Bytes::from_array(&env, &[0x01, 0x02, 0x03, 0x04, 0x05]);
357
256
  let mut reader = BufferReader::new(&bytes);
358
257
 
359
- let value = reader.read_u8();
360
- assert_eq!(value, u8::MAX);
258
+ reader.read_u16(); // Position is now 2
259
+ assert_eq!(reader.position(), 2);
260
+ let remaining = reader.read_bytes_until_end();
261
+ assert_eq!(remaining.len(), 3);
262
+ assert_eq!(remaining.get(0).unwrap(), 0x03);
263
+ assert_eq!(remaining.get(2).unwrap(), 0x05);
264
+ assert_eq!(reader.remaining_len(), 0);
361
265
  }
362
266
 
363
267
  #[test]
364
- fn test_read_multiple_u8() {
268
+ fn test_read_bytes_until_end_when_exhausted() {
365
269
  let env = Env::default();
366
270
  let bytes = Bytes::from_array(&env, &[0x01, 0x02, 0x03, 0x04]);
367
271
  let mut reader = BufferReader::new(&bytes);
368
272
 
369
- assert_eq!(reader.read_u8(), 0x01);
370
- assert_eq!(reader.read_u8(), 0x02);
371
- assert_eq!(reader.read_u8(), 0x03);
372
- assert_eq!(reader.read_u8(), 0x04);
273
+ // Exhaust buffer by reading all bytes
274
+ reader.read_bytes(4);
275
+ assert_eq!(reader.remaining_len(), 0);
276
+
277
+ // read_bytes_until_end on exhausted buffer should return empty Bytes
278
+ let empty = reader.read_bytes_until_end();
279
+ assert_eq!(empty.len(), 0);
280
+ assert_eq!(reader.remaining_len(), 0);
373
281
  }
374
282
 
375
283
  #[test]
376
- #[should_panic]
377
- fn test_read_u8_insufficient_bytes() {
284
+ fn test_read_bytes_until_end_on_empty_buffer() {
378
285
  let env = Env::default();
379
286
  let bytes = Bytes::from_array(&env, &[]);
380
287
  let mut reader = BufferReader::new(&bytes);
381
288
 
382
- reader.read_u8();
289
+ assert_eq!(reader.remaining_len(), 0);
290
+ let empty = reader.read_bytes_until_end();
291
+ assert_eq!(empty.len(), 0);
292
+ assert_eq!(reader.remaining_len(), 0);
293
+ assert_eq!(reader.position(), 0);
383
294
  }
384
295
 
385
- // Tests for read_u16() method
386
- #[test]
387
- fn test_read_u16() {
388
- let env = Env::default();
389
- let bytes = Bytes::from_array(&env, &[0x12, 0x34]);
390
- let mut reader = BufferReader::new(&bytes);
391
-
392
- let value = reader.read_u16();
393
- assert_eq!(value, 0x1234u16);
394
- }
296
+ // ============================================
297
+ // read_address tests
298
+ // ============================================
395
299
 
396
300
  #[test]
397
- fn test_read_u16_zero() {
301
+ fn test_read_address_contract_roundtrip() {
398
302
  let env = Env::default();
399
- let bytes = Bytes::from_array(&env, &[0x00, 0x00]);
400
- let mut reader = BufferReader::new(&bytes);
401
-
402
- let value = reader.read_u16();
403
- assert_eq!(value, 0u16);
303
+ let address = Address::generate(&env);
304
+ let payload = address.to_payload().unwrap();
305
+ assert!(matches!(payload, AddressPayload::ContractIdHash(_)));
306
+ test_address_roundtrip(&env, &address);
404
307
  }
405
308
 
406
309
  #[test]
407
- fn test_read_u16_max_value() {
310
+ fn test_read_address_account_roundtrip() {
408
311
  let env = Env::default();
409
- let bytes = Bytes::from_array(&env, &[0xFF, 0xFF]);
410
- let mut reader = BufferReader::new(&bytes);
411
-
412
- let value = reader.read_u16();
413
- assert_eq!(value, u16::MAX);
312
+ let account_payload = BytesN::<32>::from_array(
313
+ &env,
314
+ &[
315
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12,
316
+ 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
317
+ ],
318
+ );
319
+ let address = Address::from_payload(&env, AddressPayload::AccountIdPublicKeyEd25519(account_payload));
320
+ let payload = address.to_payload().unwrap();
321
+ assert!(matches!(payload, AddressPayload::AccountIdPublicKeyEd25519(_)));
322
+ test_address_roundtrip(&env, &address);
414
323
  }
415
324
 
416
325
  #[test]
417
- fn test_read_multiple_u16() {
326
+ fn test_read_address_all_zero_payload() {
418
327
  let env = Env::default();
419
- let bytes = Bytes::from_array(&env, &[0x00, 0x01, 0x00, 0x02, 0x00, 0x03]);
420
- let mut reader = BufferReader::new(&bytes);
421
-
422
- assert_eq!(reader.read_u16(), 1u16);
423
- assert_eq!(reader.read_u16(), 2u16);
424
- assert_eq!(reader.read_u16(), 3u16);
328
+ let zero_payload = BytesN::<32>::from_array(&env, &[0x00; 32]);
329
+ let addr = Address::from_payload(&env, AddressPayload::AccountIdPublicKeyEd25519(zero_payload));
330
+ test_address_roundtrip(&env, &addr);
425
331
  }
426
332
 
427
333
  #[test]
428
- #[should_panic]
429
- fn test_read_u16_insufficient_bytes_empty() {
334
+ fn test_read_address_mixed_types_roundtrip() {
430
335
  let env = Env::default();
431
- let bytes = Bytes::from_array(&env, &[]);
432
- let mut reader = BufferReader::new(&bytes);
433
-
434
- reader.read_u16();
435
- }
336
+ let contract_addr = Address::generate(&env);
337
+ let account_payload = BytesN::<32>::from_array(&env, &[0x42; 32]);
338
+ let account_addr = Address::from_payload(&env, AddressPayload::AccountIdPublicKeyEd25519(account_payload));
436
339
 
437
- #[test]
438
- #[should_panic]
439
- fn test_read_u16_insufficient_bytes_one() {
440
- let env = Env::default();
441
- let bytes = Bytes::from_array(&env, &[0x01]);
442
- let mut reader = BufferReader::new(&bytes);
340
+ let mut writer = BufferWriter::new(&env);
341
+ writer.write_address(&contract_addr).write_address(&account_addr);
342
+ let bytes = writer.to_bytes();
443
343
 
444
- reader.read_u16();
445
- }
344
+ assert_eq!(bytes.len(), 66); // 33 bytes per address
446
345
 
447
- // Tests for read_u256() method
448
- #[test]
449
- fn test_read_u256() {
450
- let env = Env::default();
451
- let bytes = Bytes::from_array(
452
- &env,
453
- &[
454
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
455
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04,
456
- ],
457
- );
458
346
  let mut reader = BufferReader::new(&bytes);
459
-
460
- let value = reader.read_u256();
461
- let expected = soroban_sdk::U256::from_u32(&env, 0x01020304);
462
- assert_eq!(value, expected);
347
+ assert_eq!(reader.read_address(), contract_addr);
348
+ assert_eq!(reader.read_address(), account_addr);
349
+ assert_eq!(reader.remaining_len(), 0);
463
350
  }
464
351
 
465
352
  #[test]
466
- fn test_read_u256_zero() {
353
+ fn test_address_encoding_golden_bytes() {
467
354
  let env = Env::default();
468
- let bytes = Bytes::from_array(
469
- &env,
470
- &[
471
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
472
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
473
- ],
474
- );
475
- let mut reader = BufferReader::new(&bytes);
476
355
 
477
- let value = reader.read_u256();
478
- let expected = soroban_sdk::U256::from_u32(&env, 0);
479
- assert_eq!(value, expected);
480
- }
356
+ let account_payload = BytesN::<32>::from_array(&env, &[0x42; 32]);
357
+ let contract_payload = BytesN::<32>::from_array(&env, &[0x99; 32]);
481
358
 
482
- #[test]
483
- fn test_read_u256_max_value() {
484
- let env = Env::default();
485
- let bytes = Bytes::from_array(
486
- &env,
487
- &[
488
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
489
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
490
- ],
491
- );
492
- let mut reader = BufferReader::new(&bytes);
359
+ let account_addr = Address::from_payload(&env, AddressPayload::AccountIdPublicKeyEd25519(account_payload.clone()));
360
+ let contract_addr = Address::from_payload(&env, AddressPayload::ContractIdHash(contract_payload.clone()));
493
361
 
494
- let value = reader.read_u256();
495
- // Verify it's a large number by checking it's not zero
496
- assert!(value > soroban_sdk::U256::from_u32(&env, 0));
497
- }
362
+ let mut w = BufferWriter::new(&env);
363
+ w.write_address(&account_addr).write_address(&contract_addr);
364
+ let bytes = w.to_bytes();
498
365
 
499
- #[test]
500
- #[should_panic]
501
- fn test_read_u256_insufficient_bytes() {
502
- let env = Env::default();
503
- let bytes = Bytes::from_array(&env, &[0x01, 0x02, 0x03, 0x04]); // Only 4 bytes, need 32
504
- let mut reader = BufferReader::new(&bytes);
366
+ // Validate raw encoding: 0/1 type byte + 32-byte payload.
367
+ let raw: [u8; 66] = bytes.to_array();
368
+ assert_eq!(raw[0], crate::buffer_writer::ACCOUNT_PAYLOAD_TYPE);
369
+ assert_eq!(raw[1..33], account_payload.to_array());
370
+ assert_eq!(raw[33], crate::buffer_writer::CONTRACT_PAYLOAD_TYPE);
371
+ assert_eq!(raw[34..66], contract_payload.to_array());
505
372
 
506
- reader.read_u256();
373
+ // Validate reader can decode the raw bytes too.
374
+ let mut r = BufferReader::new(&bytes);
375
+ assert_eq!(r.read_address(), account_addr);
376
+ assert_eq!(r.read_address(), contract_addr);
377
+ assert_eq!(r.remaining_len(), 0);
507
378
  }
508
379
 
509
- // Tests for read_bytes_until_end() method
510
380
  #[test]
511
- fn test_read_bytes_until_end() {
381
+ fn test_read_address_with_other_data_roundtrip() {
512
382
  let env = Env::default();
513
- let bytes = Bytes::from_array(&env, &[0x01, 0x02, 0x03, 0x04, 0x05, 0x06]);
514
- let mut reader = BufferReader::new(&bytes);
383
+ let address = Address::generate(&env);
515
384
 
516
- reader.read_bytes(2); // Read first 2 bytes
385
+ let mut writer = BufferWriter::new(&env);
386
+ writer.write_u32(0x12345678).write_address(&address).write_u64(0xAABBCCDDEEFF0011);
387
+ let bytes = writer.to_bytes();
517
388
 
518
- let remaining = reader.read_bytes_until_end();
519
- assert_eq!(remaining.len(), 4);
520
- assert_eq!(remaining.get(0).unwrap(), 0x03);
521
- assert_eq!(remaining.get(1).unwrap(), 0x04);
522
- assert_eq!(remaining.get(2).unwrap(), 0x05);
523
- assert_eq!(remaining.get(3).unwrap(), 0x06);
524
- }
389
+ assert_eq!(bytes.len(), 4 + 33 + 8);
525
390
 
526
- #[test]
527
- fn test_read_bytes_until_end_entire_buffer() {
528
- let env = Env::default();
529
- let bytes = Bytes::from_array(&env, &[0xAA, 0xBB, 0xCC]);
530
391
  let mut reader = BufferReader::new(&bytes);
531
-
532
- let remaining = reader.read_bytes_until_end();
533
- assert_eq!(remaining.len(), 3);
534
- assert_eq!(remaining.get(0).unwrap(), 0xAA);
535
- assert_eq!(remaining.get(1).unwrap(), 0xBB);
536
- assert_eq!(remaining.get(2).unwrap(), 0xCC);
392
+ assert_eq!(reader.read_u32(), 0x12345678);
393
+ assert_eq!(reader.read_address(), address);
394
+ assert_eq!(reader.read_u64(), 0xAABBCCDDEEFF0011);
395
+ assert_eq!(reader.remaining_len(), 0);
537
396
  }
538
397
 
539
398
  #[test]
540
- fn test_read_bytes_until_end_empty() {
399
+ #[should_panic(expected = "Error(Contract, #1001)")]
400
+ fn test_read_address_invalid_payload_type() {
541
401
  let env = Env::default();
542
- let bytes = Bytes::from_array(&env, &[0x01, 0x02]);
543
- let mut reader = BufferReader::new(&bytes);
544
-
545
- reader.read_bytes(2); // Exhaust the buffer
546
-
547
- let remaining = reader.read_bytes_until_end();
548
- assert_eq!(remaining.len(), 0);
549
- }
402
+ // Create bytes with invalid payload type (not 0 or 1)
403
+ let mut writer = BufferWriter::new(&env);
404
+ writer.write_u8(0xFF); // Invalid payload type
405
+ writer.write_bytes_n(&BytesN::<32>::from_array(&env, &[0x42; 32]));
406
+ let bytes = writer.to_bytes();
550
407
 
551
- #[test]
552
- fn test_read_bytes_until_end_updates_position() {
553
- let env = Env::default();
554
- let bytes = Bytes::from_array(&env, &[0x01, 0x02, 0x03, 0x04]);
555
408
  let mut reader = BufferReader::new(&bytes);
556
-
557
- reader.read_bytes(1);
558
- let _remaining = reader.read_bytes_until_end();
559
-
560
- // After read_bytes_until_end, position should be at the end
561
- assert_eq!(reader.remaining(), 0);
409
+ reader.read_address(); // Should panic with BufferReaderError::InvalidAddressPayload (10001)
562
410
  }
563
411
 
564
- // Tests for len() method
412
+ // ============================================
413
+ // read_address_payload tests
414
+ // ============================================
415
+
565
416
  #[test]
566
- fn test_len() {
417
+ fn test_read_address_payload() {
567
418
  let env = Env::default();
568
- let bytes = Bytes::from_array(&env, &[0x01, 0x02, 0x03, 0x04, 0x05]);
569
- let reader = BufferReader::new(&bytes);
419
+ let address = Address::generate(&env);
420
+ let expected_payload = address.to_payload().unwrap();
570
421
 
571
- assert_eq!(reader.len(), 5);
572
- }
422
+ let mut writer = BufferWriter::new(&env);
423
+ writer.write_address_payload(&address);
424
+ let bytes = writer.to_bytes();
573
425
 
574
- #[test]
575
- fn test_len_empty_buffer() {
576
- let env = Env::default();
577
- let bytes = Bytes::from_array(&env, &[]);
578
- let reader = BufferReader::new(&bytes);
426
+ assert_eq!(bytes.len(), 32); // Only payload, no type byte
579
427
 
580
- assert_eq!(reader.len(), 0);
428
+ let mut reader = BufferReader::new(&bytes);
429
+ let payload = reader.read_address_payload();
430
+ assert_address_payload_matches(payload, expected_payload);
431
+ assert_eq!(reader.remaining_len(), 0);
581
432
  }
582
433
 
583
434
  #[test]
584
- fn test_len_unchanged_after_read() {
435
+ #[should_panic(expected = "Error(Contract, #1000)")]
436
+ fn test_read_address_payload_insufficient_bytes() {
585
437
  let env = Env::default();
586
- let bytes = Bytes::from_array(&env, &[0x01, 0x02, 0x03, 0x04]);
438
+ let bytes = Bytes::from_array(&env, &[0x00; 31]); // Need 32 bytes
587
439
  let mut reader = BufferReader::new(&bytes);
588
-
589
- assert_eq!(reader.len(), 4);
590
- reader.read_bytes(2);
591
- assert_eq!(reader.len(), 4); // len() should not change
440
+ let _payload: BytesN<32> = reader.read_address_payload();
592
441
  }
593
442
 
594
- // Tests for remaining() method
595
- #[test]
596
- fn test_remaining_initial() {
597
- let env = Env::default();
598
- let bytes = Bytes::from_array(&env, &[0x01, 0x02, 0x03, 0x04, 0x05]);
599
- let reader = BufferReader::new(&bytes);
600
-
601
- assert_eq!(reader.remaining(), 5);
602
- }
443
+ // ============================================
444
+ // position tests
445
+ // ============================================
603
446
 
604
447
  #[test]
605
- fn test_remaining_after_read() {
448
+ fn test_position_operations() {
606
449
  let env = Env::default();
607
- let bytes = Bytes::from_array(&env, &[0x01, 0x02, 0x03, 0x04, 0x05, 0x06]);
450
+ let bytes = Bytes::from_array(&env, &[0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a]);
608
451
  let mut reader = BufferReader::new(&bytes);
609
452
 
610
- reader.read_bytes(2);
611
- assert_eq!(reader.remaining(), 4);
453
+ // Test 1: Initial state
454
+ assert_eq!(reader.position(), 0);
455
+ assert_eq!(reader.remaining_len(), 10);
456
+ assert_eq!(reader.len(), 10);
457
+ assert!(!reader.is_empty());
612
458
 
613
- reader.read_bytes(3);
614
- assert_eq!(reader.remaining(), 1);
459
+ // Test 2: Read and check position/remaining relationship
460
+ reader.read_u32();
461
+ assert_eq!(reader.position(), 4);
462
+ assert_eq!(reader.remaining_len(), 6);
615
463
 
616
- reader.read_bytes(1);
617
- assert_eq!(reader.remaining(), 0);
618
- }
464
+ // Test 3: Skip operation
465
+ reader.skip(2);
466
+ assert_eq!(reader.position(), 6);
467
+ assert_eq!(reader.remaining_len(), 4);
619
468
 
620
- #[test]
621
- fn test_remaining_empty_buffer() {
622
- let env = Env::default();
623
- let bytes = Bytes::from_array(&env, &[]);
624
- let reader = BufferReader::new(&bytes);
469
+ // Test 4: Rewind operation
470
+ reader.rewind(3);
471
+ assert_eq!(reader.position(), 3);
472
+ assert_eq!(reader.remaining_len(), 7);
625
473
 
626
- assert_eq!(reader.remaining(), 0);
627
- }
474
+ // Test 5: Set position operation
475
+ reader.seek(5);
476
+ assert_eq!(reader.position(), 5);
477
+ assert_eq!(reader.remaining_len(), 5);
628
478
 
629
- #[test]
630
- fn test_remaining_after_rewind() {
631
- let env = Env::default();
632
- let bytes = Bytes::from_array(&env, &[0x01, 0x02, 0x03, 0x04]);
633
- let mut reader = BufferReader::new(&bytes);
479
+ // Test 6: Set position and read
480
+ reader.seek(1);
481
+ assert_eq!(reader.position(), 1);
482
+ assert_eq!(reader.read_u8(), 0x02);
634
483
 
635
- reader.read_bytes(3);
636
- assert_eq!(reader.remaining(), 1);
484
+ // Test 7: Method chaining - skip -> skip -> read
485
+ reader.seek(0);
486
+ let value = reader.skip(2).skip(1).read_u8();
487
+ assert_eq!(value, 0x04);
488
+ assert_eq!(reader.position(), 4);
637
489
 
490
+ // Test 8: Method chaining - rewind -> read
638
491
  reader.rewind(2);
639
- assert_eq!(reader.remaining(), 3);
640
- }
641
-
642
- #[test]
643
- fn test_read_u128() {
644
- let env = Env::default();
645
- // Create bytes representing u128 value 0x0102030405060708090a0b0c0d0e0f10
646
- let bytes = Bytes::from_array(
647
- &env,
648
- &[0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10],
649
- );
650
- let mut reader = BufferReader::new(&bytes);
492
+ let value = reader.read_u8();
493
+ assert_eq!(value, 0x03);
494
+ assert_eq!(reader.position(), 3);
651
495
 
652
- let value = reader.read_u128();
653
- assert_eq!(value, 0x0102030405060708090a0b0c0d0e0f10u128);
496
+ // Test 9: Method chaining - seek -> read
497
+ let value = reader.seek(0).read_u8();
498
+ assert_eq!(value, 0x01);
499
+ assert_eq!(reader.position(), 1);
654
500
  }
655
501
 
656
- #[test]
657
- fn test_read_u128_zero() {
658
- let env = Env::default();
659
- let bytes = Bytes::from_array(&env, &[0x00; 16]);
660
- let mut reader = BufferReader::new(&bytes);
661
-
662
- let value = reader.read_u128();
663
- assert_eq!(value, 0u128);
664
- }
502
+ // ============================================
503
+ // seek tests
504
+ // ============================================
665
505
 
666
506
  #[test]
667
- fn test_read_u128_max_value() {
507
+ fn test_seek_boundary_values() {
668
508
  let env = Env::default();
669
- let bytes = Bytes::from_array(&env, &[0xFF; 16]);
509
+ let bytes = Bytes::from_array(&env, &[0x01, 0x02, 0x03, 0x04]);
670
510
  let mut reader = BufferReader::new(&bytes);
671
511
 
672
- let value = reader.read_u128();
673
- assert_eq!(value, u128::MAX);
674
- }
512
+ // Set to start
513
+ reader.seek(0);
514
+ assert_eq!(reader.position(), 0);
515
+ assert_eq!(reader.read_u8(), 0x01);
675
516
 
676
- #[test]
677
- fn test_read_u128_specific_value() {
678
- let env = Env::default();
679
- // Test with a specific value: 200000 (0x030d40)
680
- let mut bytes_array = [0u8; 16];
681
- // Fill with zeros except for the last 3 bytes
682
- bytes_array[13] = 0x03;
683
- bytes_array[14] = 0x0d;
684
- bytes_array[15] = 0x40;
685
- let bytes = Bytes::from_array(&env, &bytes_array);
686
- let mut reader = BufferReader::new(&bytes);
517
+ // Set to end (exact boundary - should be valid)
518
+ reader.seek(4);
519
+ assert_eq!(reader.position(), 4);
520
+ assert_eq!(reader.remaining_len(), 0);
687
521
 
688
- let value = reader.read_u128();
689
- assert_eq!(value, 200000u128);
522
+ // Set to middle
523
+ reader.seek(2);
524
+ assert_eq!(reader.position(), 2);
525
+ assert_eq!(reader.read_u8(), 0x03);
690
526
  }
691
527
 
692
528
  #[test]
693
- fn test_read_bytes_n() {
529
+ fn test_seek_on_empty_buffer() {
694
530
  let env = Env::default();
695
- // Create 32 bytes with a pattern
696
- let bytes = Bytes::from_array(
697
- &env,
698
- &[
699
- 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12,
700
- 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
701
- ],
702
- );
531
+ let bytes = Bytes::from_array(&env, &[]);
703
532
  let mut reader = BufferReader::new(&bytes);
704
533
 
705
- let value = reader.read_bytes_n::<32>();
706
- let expected = BytesN::<32>::from_array(
707
- &env,
708
- &[
709
- 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12,
710
- 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
711
- ],
712
- );
713
- assert_eq!(value, expected);
534
+ // Should be able to set position to 0 on empty buffer
535
+ reader.seek(0);
536
+ assert_eq!(reader.position(), 0);
537
+ assert_eq!(reader.remaining_len(), 0);
714
538
  }
715
539
 
716
540
  #[test]
717
- fn test_read_bytes_n_zeros() {
541
+ #[should_panic(expected = "Error(Contract, #1000)")]
542
+ fn test_seek_beyond_buffer() {
718
543
  let env = Env::default();
719
- let bytes = Bytes::from_array(&env, &[0x00; 32]);
544
+ let bytes = Bytes::from_array(&env, &[0x01, 0x02, 0x03, 0x04]);
720
545
  let mut reader = BufferReader::new(&bytes);
721
-
722
- let value = reader.read_bytes_n::<32>();
723
- let expected = BytesN::<32>::from_array(&env, &[0x00; 32]);
724
- assert_eq!(value, expected);
546
+ reader.seek(5); // Buffer length is 4, position 5 is invalid
725
547
  }
726
548
 
727
- #[test]
728
- fn test_read_bytes_n_all_ones() {
729
- let env = Env::default();
730
- let bytes = Bytes::from_array(&env, &[0xFF; 32]);
731
- let mut reader = BufferReader::new(&bytes);
732
-
733
- let value = reader.read_bytes_n::<32>();
734
- let expected = BytesN::<32>::from_array(&env, &[0xFF; 32]);
735
- assert_eq!(value, expected);
736
- }
549
+ // ============================================
550
+ // skip tests
551
+ // ============================================
737
552
 
738
553
  #[test]
739
- fn test_read_bytes_n_different_sizes() {
554
+ fn test_skip_zero() {
740
555
  let env = Env::default();
741
- // Create buffer with 4 + 8 + 16 = 28 bytes
742
- let bytes = Bytes::from_array(
743
- &env,
744
- &[
745
- 0x01, 0x02, 0x03, 0x04, // 4 bytes
746
- 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, // 8 bytes
747
- 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
748
- 0x1c, // 16 bytes
749
- ],
750
- );
556
+ let bytes = Bytes::from_array(&env, &[0x01, 0x02, 0x03, 0x04]);
751
557
  let mut reader = BufferReader::new(&bytes);
752
558
 
753
- let val4: BytesN<4> = reader.read_bytes_n();
754
- assert_eq!(val4, BytesN::<4>::from_array(&env, &[0x01, 0x02, 0x03, 0x04]));
559
+ reader.read_u8(); // Position is now 1
560
+ assert_eq!(reader.position(), 1);
755
561
 
756
- let val8: BytesN<8> = reader.read_bytes_n();
757
- assert_eq!(val8, BytesN::<8>::from_array(&env, &[0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c]));
758
-
759
- let val16: BytesN<16> = reader.read_bytes_n();
760
- assert_eq!(
761
- val16,
762
- BytesN::<16>::from_array(
763
- &env,
764
- &[0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c]
765
- )
766
- );
767
-
768
- assert_eq!(reader.remaining(), 0);
562
+ // Skip zero should be no-op
563
+ reader.skip(0);
564
+ assert_eq!(reader.position(), 1);
769
565
  }
770
566
 
771
567
  #[test]
772
- fn test_read_bytes_n_address_pattern() {
568
+ fn test_skip_to_exact_end() {
773
569
  let env = Env::default();
774
- // Test with a typical Ethereum-style address padded to 32 bytes
775
- let bytes = Bytes::from_array(
776
- &env,
777
- &[
778
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xf3, 0x9f, 0xd6, 0xe5, 0x1a, 0xad, 0x88, 0xf6, 0xf4, 0xce, 0x6a, 0xb8,
779
- 0x82, 0x72, 0x79, 0xcf, 0xff, 0xb9, 0x22, 0x66,
780
- ],
781
- );
570
+ let bytes = Bytes::from_array(&env, &[0x01, 0x02, 0x03, 0x04]);
782
571
  let mut reader = BufferReader::new(&bytes);
783
572
 
784
- let value = reader.read_bytes_n::<32>();
785
- let expected = BytesN::<32>::from_array(
786
- &env,
787
- &[
788
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xf3, 0x9f, 0xd6, 0xe5, 0x1a, 0xad, 0x88, 0xf6, 0xf4, 0xce, 0x6a, 0xb8,
789
- 0x82, 0x72, 0x79, 0xcf, 0xff, 0xb9, 0x22, 0x66,
790
- ],
791
- );
792
- assert_eq!(value, expected);
793
- }
794
-
795
- #[test]
796
- fn test_sequential_reads_with_u128_and_bytes32() {
797
- let env = Env::default();
798
-
799
- // Create a buffer with:
800
- // - u8: 0x01
801
- // - u16: 0x0011
802
- // - u128: 200000
803
- // - bytes32: all 0x42s
804
- let mut final_bytes = Bytes::new(&env);
805
-
806
- // u8
807
- final_bytes.push_back(0x01);
808
-
809
- // u16
810
- final_bytes.extend_from_slice(&[0x00, 0x11]);
811
-
812
- // u128 (200000)
813
- final_bytes.extend_from_slice(&200000u128.to_be_bytes());
814
-
815
- // bytes32
816
- final_bytes.extend_from_slice(&[0x42; 32]);
817
-
818
- let mut reader = BufferReader::new(&final_bytes);
819
-
820
- // Read in sequence
821
- let val1 = reader.read_u8();
822
- assert_eq!(val1, 0x01);
823
-
824
- let val2 = reader.read_u16();
825
- assert_eq!(val2, 0x0011);
573
+ // Skip to exactly the end (boundary case)
574
+ reader.skip(4);
575
+ assert_eq!(reader.position(), 4);
576
+ assert_eq!(reader.remaining_len(), 0);
826
577
 
827
- let val3 = reader.read_u128();
828
- assert_eq!(val3, 200000u128);
829
-
830
- let val4 = reader.read_bytes_n::<32>();
831
- let expected = BytesN::<32>::from_array(&env, &[0x42; 32]);
832
- assert_eq!(val4, expected);
833
-
834
- // Should have read everything
835
- assert_eq!(reader.remaining(), 0);
578
+ // Should be able to read_bytes_until_end without error (returns empty)
579
+ let empty = reader.read_bytes_until_end();
580
+ assert_eq!(empty.len(), 0);
836
581
  }
837
582
 
838
583
  #[test]
839
- fn test_read_arbitrary_size() {
584
+ #[should_panic(expected = "Error(Contract, #1000)")]
585
+ fn test_skip_beyond_buffer() {
840
586
  let env = Env::default();
841
- let bytes = Bytes::from_array(&env, &[0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]);
587
+ let bytes = Bytes::from_array(&env, &[0x01, 0x02, 0x03, 0x04]);
842
588
  let mut reader = BufferReader::new(&bytes);
843
-
844
- // Read 4 bytes
845
- let chunk1 = reader.read_bytes(4);
846
- assert_eq!(chunk1.len(), 4);
847
- assert_eq!(chunk1.get(0).unwrap(), 0x01);
848
- assert_eq!(chunk1.get(3).unwrap(), 0x04);
849
-
850
- // Read remaining 4 bytes
851
- let chunk2 = reader.read_bytes(4);
852
- assert_eq!(chunk2.len(), 4);
853
- assert_eq!(chunk2.get(0).unwrap(), 0x05);
854
- assert_eq!(chunk2.get(3).unwrap(), 0x08);
855
-
856
- // All bytes consumed
857
- assert_eq!(reader.remaining(), 0);
589
+ reader.skip(5);
858
590
  }
859
591
 
592
+ // ============================================
593
+ // rewind tests
594
+ // ============================================
595
+
860
596
  #[test]
861
- #[should_panic]
862
- fn test_read_insufficient_bytes() {
597
+ fn test_rewind_zero() {
863
598
  let env = Env::default();
864
599
  let bytes = Bytes::from_array(&env, &[0x01, 0x02, 0x03, 0x04]);
865
600
  let mut reader = BufferReader::new(&bytes);
866
601
 
867
- // Try to read more bytes than available
868
- // Should panic with InsufficientBytes error
869
- reader.read_bytes(10);
602
+ reader.read_u8(); // Position is now 1
603
+ assert_eq!(reader.position(), 1);
604
+
605
+ // Rewind zero should be no-op
606
+ reader.rewind(0);
607
+ assert_eq!(reader.position(), 1);
870
608
  }
871
609
 
872
610
  #[test]
873
- #[should_panic]
874
- fn test_read_insufficient_bytes_after_partial_read() {
611
+ #[should_panic(expected = "Error(Contract, #1000)")]
612
+ fn test_rewind_beyond_start() {
875
613
  let env = Env::default();
876
614
  let bytes = Bytes::from_array(&env, &[0x01, 0x02, 0x03, 0x04]);
877
615
  let mut reader = BufferReader::new(&bytes);
878
-
879
- // Read 2 bytes successfully
880
- let _chunk = reader.read_bytes(2);
881
- assert_eq!(reader.remaining(), 2);
882
-
883
- // Try to read 3 bytes when only 2 remain
884
- // Should panic with InsufficientBytes error
885
- reader.read_bytes(3);
616
+ reader.read_bytes(2);
617
+ reader.rewind(3); // Can only rewind 2
886
618
  }
887
619
 
888
- // Tests for read_address() method
889
620
  #[test]
890
- fn test_read_address_contract_roundtrip() {
621
+ #[should_panic(expected = "Error(Contract, #1000)")]
622
+ fn test_rewind_from_start() {
891
623
  let env = Env::default();
892
-
893
- // Address::generate() creates a Contract address
894
- let original_address = Address::generate(&env);
895
- let payload = original_address.to_payload().unwrap();
896
- assert!(matches!(payload, AddressPayload::ContractIdHash(_)));
897
-
898
- // Serialize using BufferWriter, then read back
899
- let mut writer = BufferWriter::new(&env);
900
- writer.write_address(&original_address);
901
- let bytes = writer.to_bytes();
902
-
624
+ let bytes = Bytes::from_array(&env, &[0x01, 0x02, 0x03]);
903
625
  let mut reader = BufferReader::new(&bytes);
904
- let read_address = reader.read_address();
905
-
906
- assert_eq!(read_address, original_address);
907
- assert_eq!(reader.remaining(), 0);
626
+ assert_eq!(reader.position(), 0);
627
+ reader.rewind(1); // Position is 0, can't rewind
908
628
  }
909
629
 
630
+ // ============================================
631
+ // buffer_access tests (buffer, env, is_empty, len, remaining)
632
+ // ============================================
633
+
910
634
  #[test]
911
- fn test_read_address_account_roundtrip() {
635
+ fn test_buffer_access_and_empty_buffer() {
912
636
  let env = Env::default();
913
637
 
914
- // Create an account address from a 32-byte payload
915
- let account_payload = BytesN::<32>::from_array(
916
- &env,
917
- &[
918
- 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12,
919
- 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
920
- ],
921
- );
922
- let original_address = Address::from_payload(&env, AddressPayload::AccountIdPublicKeyEd25519(account_payload));
923
- let payload = original_address.to_payload().unwrap();
924
- assert!(matches!(payload, AddressPayload::AccountIdPublicKeyEd25519(_)));
925
-
926
- // Serialize using BufferWriter, then read back
927
- let mut writer = BufferWriter::new(&env);
928
- writer.write_address(&original_address);
929
- let bytes = writer.to_bytes();
930
-
931
- let mut reader = BufferReader::new(&bytes);
932
- let read_address = reader.read_address();
638
+ // Test 1: Buffer and env access
639
+ let bytes1 = Bytes::from_array(&env, &[0x01, 0x02, 0x03, 0x04]);
640
+ let mut reader1 = BufferReader::new(&bytes1);
641
+ reader1.read_u16();
642
+ let buffer = reader1.buffer();
643
+ assert_eq!(buffer.len(), 4);
644
+ assert_eq!(buffer.get(0).unwrap(), 0x01);
645
+ let _new_bytes = Bytes::from_array(reader1.env(), &[0x03, 0x04]);
933
646
 
934
- assert_eq!(read_address, original_address);
935
- assert_eq!(reader.remaining(), 0);
647
+ // Test 2: Empty buffer
648
+ let bytes2 = Bytes::from_array(&env, &[]);
649
+ let reader2 = BufferReader::new(&bytes2);
650
+ assert!(reader2.is_empty());
651
+ assert_eq!(reader2.len(), 0);
652
+ assert_eq!(reader2.remaining_len(), 0);
653
+ assert_eq!(reader2.position(), 0);
936
654
  }
937
655
 
938
656
  #[test]
939
- fn test_read_address_mixed_types_roundtrip() {
657
+ fn test_is_empty_semantics() {
658
+ // is_empty() checks if the BUFFER is empty, not if remaining bytes is zero
940
659
  let env = Env::default();
941
660
 
942
- // Generate contract address
943
- let contract_addr = Address::generate(&env);
944
-
945
- // Create account address
946
- let account_payload = BytesN::<32>::from_array(&env, &[0x42; 32]);
947
- let account_addr = Address::from_payload(&env, AddressPayload::AccountIdPublicKeyEd25519(account_payload));
661
+ // Non-empty buffer: is_empty should always be false regardless of position
662
+ let bytes = Bytes::from_array(&env, &[0x01, 0x02, 0x03, 0x04]);
663
+ let mut reader = BufferReader::new(&bytes);
948
664
 
949
- // Serialize both addresses (33 * 2 = 66 bytes)
950
- let mut writer = BufferWriter::new(&env);
951
- writer.write_address(&contract_addr);
952
- writer.write_address(&account_addr);
953
- let bytes = writer.to_bytes();
665
+ assert!(!reader.is_empty());
666
+ reader.read_bytes(4); // Exhaust buffer
667
+ assert_eq!(reader.remaining_len(), 0);
668
+ assert!(!reader.is_empty()); // Buffer itself is NOT empty, just fully read
954
669
 
955
- assert_eq!(bytes.len(), 66); // 33 bytes per address
956
-
957
- let mut reader = BufferReader::new(&bytes);
958
- assert_eq!(reader.read_address(), contract_addr);
959
- assert_eq!(reader.read_address(), account_addr);
960
- assert_eq!(reader.remaining(), 0);
670
+ // Empty buffer: is_empty should be true
671
+ let empty_bytes = Bytes::from_array(&env, &[]);
672
+ let empty_reader = BufferReader::new(&empty_bytes);
673
+ assert!(empty_reader.is_empty());
961
674
  }
962
675
 
963
676
  #[test]
964
- fn test_read_address_with_other_data_roundtrip() {
677
+ fn test_len_immutable_after_reads() {
678
+ // len() returns total buffer length, should not change after reads
965
679
  let env = Env::default();
680
+ let bytes = Bytes::from_array(&env, &[0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]);
681
+ let mut reader = BufferReader::new(&bytes);
966
682
 
967
- let original_address = Address::generate(&env);
968
-
969
- // Create buffer: u32 + address (33 bytes) + u64
970
- let mut writer = BufferWriter::new(&env);
971
- writer.write_u32(0x12345678);
972
- writer.write_address(&original_address);
973
- writer.write_u64(0xAABBCCDDEEFF0011);
974
- let bytes = writer.to_bytes();
683
+ assert_eq!(reader.len(), 8);
975
684
 
976
- assert_eq!(bytes.len(), 4 + 33 + 8);
685
+ reader.read_u32();
686
+ assert_eq!(reader.len(), 8); // Still 8
687
+
688
+ reader.skip(2);
689
+ assert_eq!(reader.len(), 8); // Still 8
690
+
691
+ reader.read_bytes_until_end();
692
+ assert_eq!(reader.len(), 8); // Still 8
693
+ }
694
+
695
+ // ============================================
696
+ // insufficient_bytes_error tests
697
+ // ============================================
698
+
699
+ #[test]
700
+ fn test_buffer_reader_invalid_length_panics_table() {
701
+ const EXPECTED: &str = "Error(Contract, #1000)";
702
+
703
+ let cases: &[(&str, &[u8], ReaderStep)] = &[
704
+ ("read_u8 empty", &[], |r: &mut BufferReader| {
705
+ r.read_u8();
706
+ }),
707
+ ("read_u16 1 byte", &[0x01], |r: &mut BufferReader| {
708
+ r.read_u16();
709
+ }),
710
+ ("read_u32 3 bytes", &[0x01, 0x02, 0x03], |r: &mut BufferReader| {
711
+ r.read_u32();
712
+ }),
713
+ ("read_u64 7 bytes", &[0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07], |r: &mut BufferReader| {
714
+ r.read_u64();
715
+ }),
716
+ ("read_u128 15 bytes", &[0x01; 15], |r: &mut BufferReader| {
717
+ r.read_u128();
718
+ }),
719
+ ("read_u256 31 bytes", &[0x01; 31], |r: &mut BufferReader| {
720
+ r.read_u256();
721
+ }),
722
+ ("read_bytes(10) from 4", &[0x01, 0x02, 0x03, 0x04], |r: &mut BufferReader| {
723
+ r.read_bytes(10);
724
+ }),
725
+ ("read_bytes_n<4> from 3", &[0x01, 0x02, 0x03], |r: &mut BufferReader| {
726
+ let _val: BytesN<4> = r.read_bytes_n();
727
+ }),
728
+ ("read_address from 32 (needs 33)", &[0x00; 32], |r: &mut BufferReader| {
729
+ r.read_address();
730
+ }),
731
+ ("read_bool empty", &[], |r: &mut BufferReader| {
732
+ r.read_bool();
733
+ }),
734
+ ];
977
735
 
978
- let mut reader = BufferReader::new(&bytes);
979
- assert_eq!(reader.read_u32(), 0x12345678);
980
- assert_eq!(reader.read_address(), original_address);
981
- assert_eq!(reader.read_u64(), 0xAABBCCDDEEFF0011);
982
- assert_eq!(reader.remaining(), 0);
736
+ for (name, raw, step) in cases {
737
+ assert_reader_panics_contains(name, raw, *step, EXPECTED);
738
+ }
983
739
  }
984
740
 
985
741
  #[test]
986
- #[should_panic]
987
- fn test_read_address_insufficient_bytes_empty() {
742
+ #[should_panic(expected = "Error(Contract, #1000)")]
743
+ fn test_read_after_buffer_exhausted() {
988
744
  let env = Env::default();
989
- let bytes = Bytes::from_array(&env, &[]);
745
+ let bytes = Bytes::from_array(&env, &[0x01, 0x02, 0x03, 0x04]);
990
746
  let mut reader = BufferReader::new(&bytes);
991
747
 
992
- // Should panic - no bytes available (need 33)
993
- reader.read_address();
748
+ let _val = reader.read_u32(); // Exhausts the buffer
749
+ assert_eq!(reader.remaining_len(), 0);
750
+ reader.read_u8(); // Should panic
994
751
  }
995
752
 
996
753
  #[test]
997
- #[should_panic]
998
- fn test_read_address_insufficient_bytes_partial() {
754
+ #[should_panic(expected = "Error(Contract, #1000)")]
755
+ fn test_read_insufficient_bytes_after_partial_read() {
999
756
  let env = Env::default();
1000
- // Only 32 bytes, need 33
1001
- let bytes = Bytes::from_array(&env, &[0x00; 32]);
757
+ let bytes = Bytes::from_array(&env, &[0x01, 0x02, 0x03, 0x04]);
1002
758
  let mut reader = BufferReader::new(&bytes);
1003
759
 
1004
- // Should panic - not enough bytes
1005
- reader.read_address();
760
+ // Read 2 bytes successfully
761
+ let _chunk = reader.read_bytes(2);
762
+ assert_eq!(reader.remaining_len(), 2);
763
+
764
+ // Try to read 3 bytes when only 2 remain
765
+ // Should panic with InsufficientBytes error
766
+ reader.read_bytes(3);
1006
767
  }