@layerzerolabs/common-utils-stellar-contracts 0.2.122
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.
- package/Cargo.toml +28 -0
- package/LICENSE +23 -0
- package/clippy.toml +7 -0
- package/package.json +43 -0
- package/rust-toolchain.toml +4 -0
- package/rustfmt.toml +15 -0
- package/src/auth.rs +48 -0
- package/src/buffer_reader.rs +194 -0
- package/src/buffer_writer.rs +138 -0
- package/src/bytes_ext.rs +18 -0
- package/src/errors.rs +82 -0
- package/src/lib.rs +20 -0
- package/src/multisig.rs +247 -0
- package/src/option_ext.rs +38 -0
- package/src/ownable.rs +227 -0
- package/src/rbac.rs +438 -0
- package/src/testing_utils.rs +180 -0
- package/src/tests/auth.rs +179 -0
- package/src/tests/buffer_reader.rs +969 -0
- package/src/tests/buffer_writer.rs +689 -0
- package/src/tests/bytes_ext.rs +160 -0
- package/src/tests/mod.rs +13 -0
- package/src/tests/multisig.rs +760 -0
- package/src/tests/option_ext.rs +18 -0
- package/src/tests/ownable.rs +822 -0
- package/src/tests/rbac.rs +559 -0
- package/src/tests/test_helper.rs +67 -0
- package/src/tests/testing_utils.rs +522 -0
- package/src/tests/ttl_configurable.rs +586 -0
- package/src/tests/ttl_extendable.rs +64 -0
- package/src/tests/upgradeable.rs +529 -0
- package/src/ttl_configurable.rs +169 -0
- package/src/ttl_extendable.rs +25 -0
- package/src/upgradeable.rs +103 -0
|
@@ -0,0 +1,689 @@
|
|
|
1
|
+
use crate::{
|
|
2
|
+
buffer_reader::BufferReader, buffer_writer::BufferWriter, bytes_ext::BytesExt,
|
|
3
|
+
tests::test_helper::assert_address_payload_matches,
|
|
4
|
+
};
|
|
5
|
+
use soroban_sdk::{address_payload::AddressPayload, testutils::Address as _, Address, Bytes, BytesN, Env, I256, U256};
|
|
6
|
+
|
|
7
|
+
/// Helper to test U256 write/read roundtrip
|
|
8
|
+
fn test_u256_roundtrip(env: &Env, value: &soroban_sdk::U256) {
|
|
9
|
+
let mut writer = BufferWriter::new(env);
|
|
10
|
+
writer.write_u256(value.clone());
|
|
11
|
+
let bytes = writer.to_bytes();
|
|
12
|
+
assert_eq!(bytes.len(), 32);
|
|
13
|
+
|
|
14
|
+
let mut reader = BufferReader::new(&bytes);
|
|
15
|
+
assert_eq!(reader.read_u256(), *value);
|
|
16
|
+
assert_eq!(reader.remaining_len(), 0);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/// Helper to test address write/read roundtrip
|
|
20
|
+
fn test_address_write_roundtrip(env: &Env, address: &Address) {
|
|
21
|
+
let mut writer = BufferWriter::new(env);
|
|
22
|
+
writer.write_address(address);
|
|
23
|
+
|
|
24
|
+
// Address is 33 bytes (1 type + 32 payload)
|
|
25
|
+
let bytes = writer.to_bytes();
|
|
26
|
+
assert_eq!(bytes.len(), 33);
|
|
27
|
+
|
|
28
|
+
let mut reader = BufferReader::new(&bytes);
|
|
29
|
+
assert_eq!(reader.read_address(), *address);
|
|
30
|
+
assert_eq!(reader.remaining_len(), 0);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// ============================================
|
|
34
|
+
// constructor tests (new, from_bytes)
|
|
35
|
+
// ============================================
|
|
36
|
+
|
|
37
|
+
#[test]
|
|
38
|
+
fn test_new_buffer_writer() {
|
|
39
|
+
let env = Env::default();
|
|
40
|
+
let writer = BufferWriter::new(&env);
|
|
41
|
+
|
|
42
|
+
assert_eq!(writer.len(), 0);
|
|
43
|
+
assert!(writer.is_empty());
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
#[test]
|
|
47
|
+
fn test_from_bytes() {
|
|
48
|
+
let env = Env::default();
|
|
49
|
+
let initial = Bytes::from_array(&env, &[0x01, 0x02]);
|
|
50
|
+
let mut writer = BufferWriter::from_bytes(initial);
|
|
51
|
+
|
|
52
|
+
writer.write_u8(0x03).write_u16(0x0405);
|
|
53
|
+
|
|
54
|
+
let bytes = writer.to_bytes();
|
|
55
|
+
assert_eq!(bytes.len(), 5);
|
|
56
|
+
assert_eq!(bytes.get(0).unwrap(), 0x01);
|
|
57
|
+
assert_eq!(bytes.get(1).unwrap(), 0x02);
|
|
58
|
+
assert_eq!(bytes.get(2).unwrap(), 0x03);
|
|
59
|
+
assert_eq!(bytes.get(3).unwrap(), 0x04);
|
|
60
|
+
assert_eq!(bytes.get(4).unwrap(), 0x05);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
#[test]
|
|
64
|
+
fn test_from_bytes_with_large_buffer() {
|
|
65
|
+
let env = Env::default();
|
|
66
|
+
let initial_data: [u8; 100] = core::array::from_fn(|i| i as u8);
|
|
67
|
+
let initial = Bytes::from_array(&env, &initial_data);
|
|
68
|
+
let mut writer = BufferWriter::from_bytes(initial);
|
|
69
|
+
|
|
70
|
+
writer.write_u32(0xDEADBEEF);
|
|
71
|
+
|
|
72
|
+
let bytes = writer.to_bytes();
|
|
73
|
+
assert_eq!(bytes.len(), 104);
|
|
74
|
+
assert_eq!(bytes.get(0).unwrap(), 0);
|
|
75
|
+
assert_eq!(bytes.get(99).unwrap(), 99);
|
|
76
|
+
// Verify appended data
|
|
77
|
+
let mut reader = BufferReader::new(&bytes);
|
|
78
|
+
reader.skip(100);
|
|
79
|
+
assert_eq!(reader.read_u32(), 0xDEADBEEF);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
#[test]
|
|
83
|
+
fn test_from_bytes_empty() {
|
|
84
|
+
let env = Env::default();
|
|
85
|
+
let empty = Bytes::new(&env);
|
|
86
|
+
let mut writer = BufferWriter::from_bytes(empty);
|
|
87
|
+
|
|
88
|
+
writer.write_u8(0x42);
|
|
89
|
+
|
|
90
|
+
let bytes = writer.to_bytes();
|
|
91
|
+
assert_eq!(bytes.len(), 1);
|
|
92
|
+
assert_eq!(bytes.get(0).unwrap(), 0x42);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// ============================================
|
|
96
|
+
// write_primitives tests (u8, u16, u32, u64, u128, i128, u256, bool)
|
|
97
|
+
// ============================================
|
|
98
|
+
|
|
99
|
+
#[test]
|
|
100
|
+
fn test_write_primitives_big_endian_golden_bytes() {
|
|
101
|
+
let env = Env::default();
|
|
102
|
+
let mut writer = BufferWriter::new(&env);
|
|
103
|
+
writer
|
|
104
|
+
.write_u8(0x12)
|
|
105
|
+
.write_u16(0x3456)
|
|
106
|
+
.write_u32(0x789ABCDE)
|
|
107
|
+
.write_u64(0x0102030405060708)
|
|
108
|
+
.write_u128(0x0102030405060708090a0b0c0d0e0f10);
|
|
109
|
+
|
|
110
|
+
let bytes = writer.to_bytes();
|
|
111
|
+
let got: [u8; 31] = bytes.to_array();
|
|
112
|
+
|
|
113
|
+
let expected: [u8; 31] = [
|
|
114
|
+
0x12, // u8
|
|
115
|
+
0x34, 0x56, // u16
|
|
116
|
+
0x78, 0x9A, 0xBC, 0xDE, // u32
|
|
117
|
+
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // u64
|
|
118
|
+
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, // u128
|
|
119
|
+
];
|
|
120
|
+
assert_eq!(got, expected);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
#[test]
|
|
124
|
+
fn test_write_signed_integers_big_endian_golden_bytes() {
|
|
125
|
+
let env = Env::default();
|
|
126
|
+
let mut writer = BufferWriter::new(&env);
|
|
127
|
+
|
|
128
|
+
writer
|
|
129
|
+
.write_i8(-1)
|
|
130
|
+
.write_i8(i8::MIN)
|
|
131
|
+
.write_i8(i8::MAX)
|
|
132
|
+
.write_i16(-1)
|
|
133
|
+
.write_i16(i16::MIN)
|
|
134
|
+
.write_i16(i16::MAX)
|
|
135
|
+
.write_i32(-1)
|
|
136
|
+
.write_i32(i32::MIN)
|
|
137
|
+
.write_i32(i32::MAX)
|
|
138
|
+
.write_i64(-1)
|
|
139
|
+
.write_i64(i64::MIN)
|
|
140
|
+
.write_i64(i64::MAX)
|
|
141
|
+
.write_i128(-1)
|
|
142
|
+
.write_i128(i128::MIN)
|
|
143
|
+
.write_i128(i128::MAX);
|
|
144
|
+
|
|
145
|
+
let bytes = writer.to_bytes();
|
|
146
|
+
assert_eq!(bytes.len(), 93);
|
|
147
|
+
let got: [u8; 93] = bytes.to_array();
|
|
148
|
+
|
|
149
|
+
// Layout:
|
|
150
|
+
// - i8: -1, MIN, MAX (3 bytes)
|
|
151
|
+
// - i16: -1, MIN, MAX (6 bytes)
|
|
152
|
+
// - i32: -1, MIN, MAX (12 bytes)
|
|
153
|
+
// - i64: -1, MIN, MAX (24 bytes)
|
|
154
|
+
// - i128: -1, MIN, MAX (48 bytes)
|
|
155
|
+
// Total = 93 bytes
|
|
156
|
+
let mut expected = [0u8; 93];
|
|
157
|
+
let mut pos = 0usize;
|
|
158
|
+
|
|
159
|
+
expected[pos] = (-1i8) as u8;
|
|
160
|
+
pos += 1;
|
|
161
|
+
expected[pos] = i8::MIN as u8;
|
|
162
|
+
pos += 1;
|
|
163
|
+
expected[pos] = i8::MAX as u8;
|
|
164
|
+
pos += 1;
|
|
165
|
+
|
|
166
|
+
expected[pos..pos + 2].copy_from_slice(&(-1i16).to_be_bytes());
|
|
167
|
+
pos += 2;
|
|
168
|
+
expected[pos..pos + 2].copy_from_slice(&i16::MIN.to_be_bytes());
|
|
169
|
+
pos += 2;
|
|
170
|
+
expected[pos..pos + 2].copy_from_slice(&i16::MAX.to_be_bytes());
|
|
171
|
+
pos += 2;
|
|
172
|
+
|
|
173
|
+
expected[pos..pos + 4].copy_from_slice(&(-1i32).to_be_bytes());
|
|
174
|
+
pos += 4;
|
|
175
|
+
expected[pos..pos + 4].copy_from_slice(&i32::MIN.to_be_bytes());
|
|
176
|
+
pos += 4;
|
|
177
|
+
expected[pos..pos + 4].copy_from_slice(&i32::MAX.to_be_bytes());
|
|
178
|
+
pos += 4;
|
|
179
|
+
|
|
180
|
+
expected[pos..pos + 8].copy_from_slice(&(-1i64).to_be_bytes());
|
|
181
|
+
pos += 8;
|
|
182
|
+
expected[pos..pos + 8].copy_from_slice(&i64::MIN.to_be_bytes());
|
|
183
|
+
pos += 8;
|
|
184
|
+
expected[pos..pos + 8].copy_from_slice(&i64::MAX.to_be_bytes());
|
|
185
|
+
pos += 8;
|
|
186
|
+
|
|
187
|
+
expected[pos..pos + 16].copy_from_slice(&(-1i128).to_be_bytes());
|
|
188
|
+
pos += 16;
|
|
189
|
+
expected[pos..pos + 16].copy_from_slice(&i128::MIN.to_be_bytes());
|
|
190
|
+
pos += 16;
|
|
191
|
+
expected[pos..pos + 16].copy_from_slice(&i128::MAX.to_be_bytes());
|
|
192
|
+
pos += 16;
|
|
193
|
+
|
|
194
|
+
assert_eq!(pos, expected.len());
|
|
195
|
+
assert_eq!(got, expected);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
#[test]
|
|
199
|
+
fn test_write_signed_integers_roundtrip() {
|
|
200
|
+
let env = Env::default();
|
|
201
|
+
let mut writer = BufferWriter::new(&env);
|
|
202
|
+
|
|
203
|
+
writer
|
|
204
|
+
.write_i8(0)
|
|
205
|
+
.write_i8(-1)
|
|
206
|
+
.write_i8(i8::MIN)
|
|
207
|
+
.write_i8(i8::MAX)
|
|
208
|
+
.write_i16(0)
|
|
209
|
+
.write_i16(-42)
|
|
210
|
+
.write_i16(i16::MIN)
|
|
211
|
+
.write_i16(i16::MAX)
|
|
212
|
+
.write_i32(0)
|
|
213
|
+
.write_i32(-42)
|
|
214
|
+
.write_i32(i32::MIN)
|
|
215
|
+
.write_i32(i32::MAX)
|
|
216
|
+
.write_i64(0)
|
|
217
|
+
.write_i64(-42)
|
|
218
|
+
.write_i64(i64::MIN)
|
|
219
|
+
.write_i64(i64::MAX)
|
|
220
|
+
.write_i128(0)
|
|
221
|
+
.write_i128(-42)
|
|
222
|
+
.write_i128(123_456_789)
|
|
223
|
+
.write_i128(i128::MIN)
|
|
224
|
+
.write_i128(i128::MAX);
|
|
225
|
+
|
|
226
|
+
let bytes = writer.to_bytes();
|
|
227
|
+
let mut reader = BufferReader::new(&bytes);
|
|
228
|
+
|
|
229
|
+
assert_eq!(reader.read_i8(), 0);
|
|
230
|
+
assert_eq!(reader.read_i8(), -1);
|
|
231
|
+
assert_eq!(reader.read_i8(), i8::MIN);
|
|
232
|
+
assert_eq!(reader.read_i8(), i8::MAX);
|
|
233
|
+
|
|
234
|
+
assert_eq!(reader.read_i16(), 0);
|
|
235
|
+
assert_eq!(reader.read_i16(), -42);
|
|
236
|
+
assert_eq!(reader.read_i16(), i16::MIN);
|
|
237
|
+
assert_eq!(reader.read_i16(), i16::MAX);
|
|
238
|
+
|
|
239
|
+
assert_eq!(reader.read_i32(), 0);
|
|
240
|
+
assert_eq!(reader.read_i32(), -42);
|
|
241
|
+
assert_eq!(reader.read_i32(), i32::MIN);
|
|
242
|
+
assert_eq!(reader.read_i32(), i32::MAX);
|
|
243
|
+
|
|
244
|
+
assert_eq!(reader.read_i64(), 0);
|
|
245
|
+
assert_eq!(reader.read_i64(), -42);
|
|
246
|
+
assert_eq!(reader.read_i64(), i64::MIN);
|
|
247
|
+
assert_eq!(reader.read_i64(), i64::MAX);
|
|
248
|
+
|
|
249
|
+
assert_eq!(reader.read_i128(), 0);
|
|
250
|
+
assert_eq!(reader.read_i128(), -42);
|
|
251
|
+
assert_eq!(reader.read_i128(), 123_456_789);
|
|
252
|
+
assert_eq!(reader.read_i128(), i128::MIN);
|
|
253
|
+
assert_eq!(reader.read_i128(), i128::MAX);
|
|
254
|
+
assert_eq!(reader.remaining_len(), 0);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
#[test]
|
|
258
|
+
fn test_write_i256_big_endian_golden_bytes_and_roundtrip() {
|
|
259
|
+
let env = Env::default();
|
|
260
|
+
|
|
261
|
+
// Golden layouts: -1, MIN, MAX, +1
|
|
262
|
+
let mut raw = [0u8; 32 * 4];
|
|
263
|
+
raw[0..32].copy_from_slice(&[0xFF; 32]); // -1
|
|
264
|
+
raw[32] = 0x80; // MIN (0x80 followed by 31x 0x00)
|
|
265
|
+
raw[64] = 0x7F; // MAX (0x7F followed by 31x 0xFF)
|
|
266
|
+
raw[65..96].copy_from_slice(&[0xFF; 31]);
|
|
267
|
+
raw[127] = 0x01; // +1
|
|
268
|
+
|
|
269
|
+
let expected_neg1 = I256::from_be_bytes(&env, &Bytes::from_slice(&env, &raw[0..32]));
|
|
270
|
+
let expected_min = I256::from_be_bytes(&env, &Bytes::from_slice(&env, &raw[32..64]));
|
|
271
|
+
let expected_max = I256::from_be_bytes(&env, &Bytes::from_slice(&env, &raw[64..96]));
|
|
272
|
+
let expected_one = I256::from_be_bytes(&env, &Bytes::from_slice(&env, &raw[96..128]));
|
|
273
|
+
|
|
274
|
+
let mut writer = BufferWriter::new(&env);
|
|
275
|
+
writer.write_i256(expected_neg1).write_i256(expected_min).write_i256(expected_max).write_i256(expected_one);
|
|
276
|
+
|
|
277
|
+
let bytes = writer.to_bytes();
|
|
278
|
+
assert_eq!(bytes.len(), 128);
|
|
279
|
+
let got: [u8; 128] = bytes.to_array();
|
|
280
|
+
assert_eq!(got, raw);
|
|
281
|
+
|
|
282
|
+
// Roundtrip through BufferReader.
|
|
283
|
+
let mut reader = BufferReader::new(&bytes);
|
|
284
|
+
let roundtrip_neg1 = I256::from_be_bytes(&env, &Bytes::from_slice(&env, &raw[0..32]));
|
|
285
|
+
let roundtrip_min = I256::from_be_bytes(&env, &Bytes::from_slice(&env, &raw[32..64]));
|
|
286
|
+
let roundtrip_max = I256::from_be_bytes(&env, &Bytes::from_slice(&env, &raw[64..96]));
|
|
287
|
+
let roundtrip_one = I256::from_be_bytes(&env, &Bytes::from_slice(&env, &raw[96..128]));
|
|
288
|
+
|
|
289
|
+
assert_eq!(reader.read_i256(), roundtrip_neg1);
|
|
290
|
+
assert_eq!(reader.read_i256(), roundtrip_min);
|
|
291
|
+
assert_eq!(reader.read_i256(), roundtrip_max);
|
|
292
|
+
assert_eq!(reader.read_i256(), roundtrip_one);
|
|
293
|
+
assert_eq!(reader.remaining_len(), 0);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
#[test]
|
|
297
|
+
fn test_write_primitives_roundtrip() {
|
|
298
|
+
let env = Env::default();
|
|
299
|
+
let mut writer = BufferWriter::new(&env);
|
|
300
|
+
|
|
301
|
+
writer
|
|
302
|
+
.write_u8(0x12)
|
|
303
|
+
.write_u16(0x3456)
|
|
304
|
+
.write_u32(0x789ABCDE)
|
|
305
|
+
.write_u64(0x0102030405060708)
|
|
306
|
+
.write_u128(0x10111213141516171819_1a1b1c1d1e1f);
|
|
307
|
+
|
|
308
|
+
let bytes = writer.to_bytes();
|
|
309
|
+
// 1 + 2 + 4 + 8 + 16 = 31
|
|
310
|
+
assert_eq!(bytes.len(), 31);
|
|
311
|
+
|
|
312
|
+
// Verify with reader
|
|
313
|
+
let mut reader = BufferReader::new(&bytes);
|
|
314
|
+
assert_eq!(reader.read_u8(), 0x12);
|
|
315
|
+
assert_eq!(reader.read_u16(), 0x3456);
|
|
316
|
+
assert_eq!(reader.read_u32(), 0x789ABCDE);
|
|
317
|
+
assert_eq!(reader.read_u64(), 0x0102030405060708);
|
|
318
|
+
assert_eq!(reader.read_u128(), 0x10111213141516171819_1a1b1c1d1e1f);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
#[test]
|
|
322
|
+
fn test_write_boundary_values() {
|
|
323
|
+
let env = Env::default();
|
|
324
|
+
let mut writer = BufferWriter::new(&env);
|
|
325
|
+
|
|
326
|
+
writer
|
|
327
|
+
.write_u8(0)
|
|
328
|
+
.write_u8(u8::MAX)
|
|
329
|
+
.write_u16(0)
|
|
330
|
+
.write_u16(u16::MAX)
|
|
331
|
+
.write_u32(0)
|
|
332
|
+
.write_u32(u32::MAX)
|
|
333
|
+
.write_u64(0)
|
|
334
|
+
.write_u64(u64::MAX)
|
|
335
|
+
.write_u128(0)
|
|
336
|
+
.write_u128(u128::MAX);
|
|
337
|
+
|
|
338
|
+
let bytes = writer.to_bytes();
|
|
339
|
+
let mut reader = BufferReader::new(&bytes);
|
|
340
|
+
|
|
341
|
+
assert_eq!(reader.read_u8(), 0);
|
|
342
|
+
assert_eq!(reader.read_u8(), u8::MAX);
|
|
343
|
+
assert_eq!(reader.read_u16(), 0);
|
|
344
|
+
assert_eq!(reader.read_u16(), u16::MAX);
|
|
345
|
+
assert_eq!(reader.read_u32(), 0);
|
|
346
|
+
assert_eq!(reader.read_u32(), u32::MAX);
|
|
347
|
+
assert_eq!(reader.read_u64(), 0);
|
|
348
|
+
assert_eq!(reader.read_u64(), u64::MAX);
|
|
349
|
+
assert_eq!(reader.read_u128(), 0);
|
|
350
|
+
assert_eq!(reader.read_u128(), u128::MAX);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
#[test]
|
|
354
|
+
fn test_write_bool() {
|
|
355
|
+
let env = Env::default();
|
|
356
|
+
let mut writer = BufferWriter::new(&env);
|
|
357
|
+
|
|
358
|
+
writer.write_bool(true).write_bool(false).write_bool(true);
|
|
359
|
+
|
|
360
|
+
let bytes = writer.to_bytes();
|
|
361
|
+
assert_eq!(bytes.len(), 3);
|
|
362
|
+
|
|
363
|
+
let mut reader = BufferReader::new(&bytes);
|
|
364
|
+
assert!(reader.read_bool());
|
|
365
|
+
assert!(!reader.read_bool());
|
|
366
|
+
assert!(reader.read_bool());
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
#[test]
|
|
370
|
+
fn test_write_u256_boundary_values() {
|
|
371
|
+
use soroban_sdk::U256;
|
|
372
|
+
let env = Env::default();
|
|
373
|
+
|
|
374
|
+
// Zero
|
|
375
|
+
let zero = U256::from_u32(&env, 0);
|
|
376
|
+
test_u256_roundtrip(&env, &zero);
|
|
377
|
+
|
|
378
|
+
// From u128::MAX
|
|
379
|
+
let from_u128_max = U256::from_u128(&env, u128::MAX);
|
|
380
|
+
test_u256_roundtrip(&env, &from_u128_max);
|
|
381
|
+
|
|
382
|
+
// Max (all 0xFF bytes)
|
|
383
|
+
let max_bytes = Bytes::from_array(&env, &[0xFF; 32]);
|
|
384
|
+
let max_u256 = U256::from_be_bytes(&env, &max_bytes);
|
|
385
|
+
test_u256_roundtrip(&env, &max_u256);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
#[test]
|
|
389
|
+
fn test_write_mixed_sizes_no_alignment_issues() {
|
|
390
|
+
let env = Env::default();
|
|
391
|
+
let mut writer = BufferWriter::new(&env);
|
|
392
|
+
|
|
393
|
+
// Test that byte-packed writes work correctly regardless of "alignment"
|
|
394
|
+
// (Soroban Bytes has no alignment requirements, but this documents the behavior)
|
|
395
|
+
writer
|
|
396
|
+
.write_u8(0x01)
|
|
397
|
+
.write_u64(0x0203040506070809)
|
|
398
|
+
.write_u8(0x0A)
|
|
399
|
+
.write_u128(0x0B0C0D0E0F101112131415161718191A)
|
|
400
|
+
.write_u8(0x1B);
|
|
401
|
+
|
|
402
|
+
assert_eq!(writer.len(), 1 + 8 + 1 + 16 + 1); // 27 bytes
|
|
403
|
+
|
|
404
|
+
let bytes = writer.to_bytes();
|
|
405
|
+
let mut reader = BufferReader::new(&bytes);
|
|
406
|
+
assert_eq!(reader.read_u8(), 0x01);
|
|
407
|
+
assert_eq!(reader.read_u64(), 0x0203040506070809);
|
|
408
|
+
assert_eq!(reader.read_u8(), 0x0A);
|
|
409
|
+
assert_eq!(reader.read_u128(), 0x0B0C0D0E0F101112131415161718191A);
|
|
410
|
+
assert_eq!(reader.read_u8(), 0x1B);
|
|
411
|
+
assert_eq!(reader.remaining_len(), 0);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
// ============================================
|
|
415
|
+
// write_bytes tests (write_bytes, write_bytes_n)
|
|
416
|
+
// ============================================
|
|
417
|
+
|
|
418
|
+
#[test]
|
|
419
|
+
fn test_write_bytes() {
|
|
420
|
+
let env = Env::default();
|
|
421
|
+
let mut writer = BufferWriter::new(&env);
|
|
422
|
+
|
|
423
|
+
let data = Bytes::from_array(&env, &[0x01, 0x02, 0x03, 0x04]);
|
|
424
|
+
writer.write_bytes(&data);
|
|
425
|
+
|
|
426
|
+
let bytes = writer.to_bytes();
|
|
427
|
+
assert_eq!(bytes.len(), 4);
|
|
428
|
+
assert_eq!(bytes.get(0).unwrap(), 0x01);
|
|
429
|
+
assert_eq!(bytes.get(3).unwrap(), 0x04);
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
#[test]
|
|
433
|
+
fn test_write_bytes_empty() {
|
|
434
|
+
let env = Env::default();
|
|
435
|
+
let mut writer = BufferWriter::new(&env);
|
|
436
|
+
|
|
437
|
+
let empty = Bytes::new(&env);
|
|
438
|
+
writer.write_bytes(&empty);
|
|
439
|
+
|
|
440
|
+
let bytes = writer.to_bytes();
|
|
441
|
+
assert_eq!(bytes.len(), 0);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
#[test]
|
|
445
|
+
fn test_write_bytes_n() {
|
|
446
|
+
let env = Env::default();
|
|
447
|
+
let mut writer = BufferWriter::new(&env);
|
|
448
|
+
|
|
449
|
+
let bytes4 = BytesN::<4>::from_array(&env, &[0x01, 0x02, 0x03, 0x04]);
|
|
450
|
+
let bytes8 = BytesN::<8>::from_array(&env, &[0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c]);
|
|
451
|
+
let bytes32 = BytesN::<32>::from_array(&env, &[0x42; 32]);
|
|
452
|
+
|
|
453
|
+
writer.write_bytes_n(&bytes4).write_bytes_n(&bytes8).write_bytes_n(&bytes32);
|
|
454
|
+
|
|
455
|
+
let bytes = writer.to_bytes();
|
|
456
|
+
assert_eq!(bytes.len(), 4 + 8 + 32);
|
|
457
|
+
|
|
458
|
+
let mut reader = BufferReader::new(&bytes);
|
|
459
|
+
assert_eq!(reader.read_bytes_n::<4>(), bytes4);
|
|
460
|
+
assert_eq!(reader.read_bytes_n::<8>(), bytes8);
|
|
461
|
+
assert_eq!(reader.read_bytes_n::<32>(), bytes32);
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
#[test]
|
|
465
|
+
fn test_write_bytes_n_array() {
|
|
466
|
+
let env = Env::default();
|
|
467
|
+
let mut writer = BufferWriter::new(&env);
|
|
468
|
+
let bytes = writer.write_array(&[0x01, 0x02, 0x03, 0x04]).to_bytes();
|
|
469
|
+
assert_eq!(bytes.len(), 4);
|
|
470
|
+
assert_eq!(bytes.get(0).unwrap(), 0x01);
|
|
471
|
+
assert_eq!(bytes.get(3).unwrap(), 0x04);
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
// ============================================
|
|
475
|
+
// write_address tests
|
|
476
|
+
// ============================================
|
|
477
|
+
|
|
478
|
+
#[test]
|
|
479
|
+
fn test_write_address_contract() {
|
|
480
|
+
let env = Env::default();
|
|
481
|
+
let address = Address::generate(&env);
|
|
482
|
+
let payload = address.to_payload().unwrap();
|
|
483
|
+
assert!(matches!(payload, AddressPayload::ContractIdHash(_)));
|
|
484
|
+
test_address_write_roundtrip(&env, &address);
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
#[test]
|
|
488
|
+
fn test_write_address_account() {
|
|
489
|
+
let env = Env::default();
|
|
490
|
+
let account_payload = BytesN::<32>::from_array(&env, &[0x42; 32]);
|
|
491
|
+
let address = Address::from_payload(&env, AddressPayload::AccountIdPublicKeyEd25519(account_payload));
|
|
492
|
+
let payload = address.to_payload().unwrap();
|
|
493
|
+
assert!(matches!(payload, AddressPayload::AccountIdPublicKeyEd25519(_)));
|
|
494
|
+
test_address_write_roundtrip(&env, &address);
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
#[test]
|
|
498
|
+
fn test_write_multiple_addresses() {
|
|
499
|
+
let env = Env::default();
|
|
500
|
+
let mut writer = BufferWriter::new(&env);
|
|
501
|
+
|
|
502
|
+
let addr1 = Address::generate(&env);
|
|
503
|
+
let addr2 = Address::generate(&env);
|
|
504
|
+
let addr3 = Address::generate(&env);
|
|
505
|
+
|
|
506
|
+
writer.write_address(&addr1).write_address(&addr2).write_address(&addr3);
|
|
507
|
+
|
|
508
|
+
let bytes = writer.to_bytes();
|
|
509
|
+
assert_eq!(bytes.len(), 99); // 33 * 3
|
|
510
|
+
|
|
511
|
+
let mut reader = BufferReader::new(&bytes);
|
|
512
|
+
assert_eq!(reader.read_address(), addr1);
|
|
513
|
+
assert_eq!(reader.read_address(), addr2);
|
|
514
|
+
assert_eq!(reader.read_address(), addr3);
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
// ============================================
|
|
518
|
+
// write_address_payload tests
|
|
519
|
+
// ============================================
|
|
520
|
+
|
|
521
|
+
#[test]
|
|
522
|
+
fn test_write_address_payload() {
|
|
523
|
+
let env = Env::default();
|
|
524
|
+
let address = Address::generate(&env);
|
|
525
|
+
let expected_payload = address.to_payload().unwrap();
|
|
526
|
+
|
|
527
|
+
let mut writer = BufferWriter::new(&env);
|
|
528
|
+
writer.write_address_payload(&address);
|
|
529
|
+
let bytes = writer.to_bytes();
|
|
530
|
+
|
|
531
|
+
// Verify it's exactly 32 bytes (no type byte)
|
|
532
|
+
assert_eq!(bytes.len(), 32);
|
|
533
|
+
|
|
534
|
+
// Verify the payload matches
|
|
535
|
+
let mut reader = BufferReader::new(&bytes);
|
|
536
|
+
let payload = reader.read_address_payload();
|
|
537
|
+
assert_address_payload_matches(payload, expected_payload);
|
|
538
|
+
assert_eq!(reader.remaining_len(), 0);
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
#[test]
|
|
542
|
+
fn test_write_address_payload_with_other_data() {
|
|
543
|
+
let env = Env::default();
|
|
544
|
+
let address = Address::generate(&env);
|
|
545
|
+
|
|
546
|
+
let mut writer = BufferWriter::new(&env);
|
|
547
|
+
writer.write_u32(0x12345678).write_address_payload(&address).write_u64(0xAABBCCDDEEFF0011);
|
|
548
|
+
let bytes = writer.to_bytes();
|
|
549
|
+
|
|
550
|
+
assert_eq!(bytes.len(), 4 + 32 + 8); // u32 + payload (32) + u64
|
|
551
|
+
|
|
552
|
+
let mut reader = BufferReader::new(&bytes);
|
|
553
|
+
assert_eq!(reader.read_u32(), 0x12345678);
|
|
554
|
+
let payload = reader.read_address_payload();
|
|
555
|
+
assert_address_payload_matches(payload, address.to_payload().unwrap());
|
|
556
|
+
assert_eq!(reader.read_u64(), 0xAABBCCDDEEFF0011);
|
|
557
|
+
assert_eq!(reader.remaining_len(), 0);
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
// ============================================
|
|
561
|
+
// chaining tests
|
|
562
|
+
// ============================================
|
|
563
|
+
|
|
564
|
+
#[test]
|
|
565
|
+
fn test_chaining_empty_bytes() {
|
|
566
|
+
let env = Env::default();
|
|
567
|
+
let mut writer = BufferWriter::new(&env);
|
|
568
|
+
|
|
569
|
+
let empty = Bytes::new(&env);
|
|
570
|
+
writer.write_bytes(&empty).write_u8(0x42).write_bytes(&empty);
|
|
571
|
+
|
|
572
|
+
let bytes = writer.to_bytes();
|
|
573
|
+
assert_eq!(bytes.len(), 1); // Only the u8
|
|
574
|
+
assert_eq!(bytes.get(0).unwrap(), 0x42);
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
// ============================================
|
|
578
|
+
// buffer_access tests (len, is_empty, env)
|
|
579
|
+
// ============================================
|
|
580
|
+
|
|
581
|
+
#[test]
|
|
582
|
+
fn test_len_after_writes() {
|
|
583
|
+
let env = Env::default();
|
|
584
|
+
let mut writer = BufferWriter::new(&env);
|
|
585
|
+
|
|
586
|
+
assert_eq!(writer.len(), 0);
|
|
587
|
+
assert!(writer.is_empty());
|
|
588
|
+
|
|
589
|
+
writer.write_u8(0x01);
|
|
590
|
+
assert_eq!(writer.len(), 1);
|
|
591
|
+
assert!(!writer.is_empty());
|
|
592
|
+
|
|
593
|
+
writer.write_u16(0x0203);
|
|
594
|
+
assert_eq!(writer.len(), 3);
|
|
595
|
+
|
|
596
|
+
writer.write_u32(0x04050607);
|
|
597
|
+
assert_eq!(writer.len(), 7);
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
#[test]
|
|
601
|
+
fn test_env_from_writer() {
|
|
602
|
+
let env = Env::default();
|
|
603
|
+
let writer = BufferWriter::new(&env);
|
|
604
|
+
|
|
605
|
+
// Verify we can use the env reference from the writer
|
|
606
|
+
let _new_bytes = Bytes::from_array(writer.env(), &[0x01, 0x02]);
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
// ============================================
|
|
610
|
+
// complex_roundtrip tests
|
|
611
|
+
// ============================================
|
|
612
|
+
|
|
613
|
+
#[test]
|
|
614
|
+
fn test_complex_message_roundtrip() {
|
|
615
|
+
let env = Env::default();
|
|
616
|
+
let mut writer = BufferWriter::new(&env);
|
|
617
|
+
|
|
618
|
+
// Simulate a complex message structure
|
|
619
|
+
let version: u8 = 1;
|
|
620
|
+
let msg_type: u16 = 0x0102;
|
|
621
|
+
let sender = Address::generate(&env);
|
|
622
|
+
let nonce: u64 = 12345678;
|
|
623
|
+
let amount = U256::from_u128(&env, 1000000000000000000u128);
|
|
624
|
+
let payload = Bytes::from_array(&env, &[0xDE, 0xAD, 0xBE, 0xEF]);
|
|
625
|
+
|
|
626
|
+
writer
|
|
627
|
+
.write_u8(version)
|
|
628
|
+
.write_u16(msg_type)
|
|
629
|
+
.write_address(&sender)
|
|
630
|
+
.write_u64(nonce)
|
|
631
|
+
.write_u256(amount.clone())
|
|
632
|
+
.write_bytes(&payload);
|
|
633
|
+
|
|
634
|
+
let bytes = writer.to_bytes();
|
|
635
|
+
|
|
636
|
+
// Read back and verify
|
|
637
|
+
let mut reader = BufferReader::new(&bytes);
|
|
638
|
+
assert_eq!(reader.read_u8(), version);
|
|
639
|
+
assert_eq!(reader.read_u16(), msg_type);
|
|
640
|
+
assert_eq!(reader.read_address(), sender);
|
|
641
|
+
assert_eq!(reader.read_u64(), nonce);
|
|
642
|
+
assert_eq!(reader.read_u256(), amount);
|
|
643
|
+
|
|
644
|
+
let read_payload = reader.read_bytes(4);
|
|
645
|
+
assert_eq!(read_payload.len(), 4);
|
|
646
|
+
assert_eq!(read_payload.get(0).unwrap(), 0xDE);
|
|
647
|
+
assert_eq!(read_payload.get(3).unwrap(), 0xEF);
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
// ============================================
|
|
651
|
+
// stress_and_edge_case tests
|
|
652
|
+
// ============================================
|
|
653
|
+
|
|
654
|
+
#[test]
|
|
655
|
+
fn test_write_large_buffer() {
|
|
656
|
+
let env = Env::default();
|
|
657
|
+
let mut writer = BufferWriter::new(&env);
|
|
658
|
+
|
|
659
|
+
// Write many items to test buffer growth
|
|
660
|
+
for i in 0..1000u32 {
|
|
661
|
+
writer.write_u32(i);
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
assert_eq!(writer.len(), 4000);
|
|
665
|
+
|
|
666
|
+
// Verify via reader
|
|
667
|
+
let bytes = writer.to_bytes();
|
|
668
|
+
let mut reader = BufferReader::new(&bytes);
|
|
669
|
+
for i in 0..1000u32 {
|
|
670
|
+
assert_eq!(reader.read_u32(), i);
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
#[test]
|
|
675
|
+
fn test_write_repeated_values() {
|
|
676
|
+
let env = Env::default();
|
|
677
|
+
let mut writer = BufferWriter::new(&env);
|
|
678
|
+
|
|
679
|
+
for _ in 0..100 {
|
|
680
|
+
writer.write_u8(0xFF);
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
let bytes = writer.to_bytes();
|
|
684
|
+
assert_eq!(bytes.len(), 100);
|
|
685
|
+
|
|
686
|
+
for i in 0..100 {
|
|
687
|
+
assert_eq!(bytes.get(i).unwrap(), 0xFF);
|
|
688
|
+
}
|
|
689
|
+
}
|