1use alloc::{
5 string::{String, ToString},
6 vec::Vec,
7};
8use core::{borrow::Borrow, cell::OnceCell};
9
10use alloy_primitives::{B256, U256, U8};
11use stylus_core::HostAccess;
12
13use super::{Erase, GlobalStorage, Storage, StorageB8, StorageGuard, StorageGuardMut, StorageType};
14use crate::{crypto, host::VM};
15
16pub struct StorageBytes {
18 root: U256,
19 base: OnceCell<U256>,
20 __stylus_host: VM,
21}
22
23impl StorageType for StorageBytes {
24 type Wraps<'a>
25 = StorageGuard<'a, StorageBytes>
26 where
27 Self: 'a;
28 type WrapsMut<'a>
29 = StorageGuardMut<'a, StorageBytes>
30 where
31 Self: 'a;
32
33 unsafe fn new(root: U256, offset: u8, host: VM) -> Self {
34 debug_assert!(offset == 0);
35 Self {
36 root,
37 base: OnceCell::new(),
38 __stylus_host: host,
39 }
40 }
41
42 fn load<'s>(self) -> Self::Wraps<'s> {
43 StorageGuard::new(self)
44 }
45
46 fn load_mut<'s>(self) -> Self::WrapsMut<'s> {
47 StorageGuardMut::new(self)
48 }
49}
50
51impl HostAccess for StorageBytes {
52 type Host = VM;
53
54 #[inline]
55 fn vm(&self) -> &Self::Host {
56 &self.__stylus_host
57 }
58}
59
60#[cfg(feature = "stylus-test")]
61impl<T> From<&T> for StorageBytes
62where
63 T: stylus_core::Host + Clone + 'static,
64{
65 fn from(host: &T) -> Self {
66 unsafe {
67 Self::new(
68 U256::ZERO,
69 0,
70 crate::host::VM {
71 host: alloc::boxed::Box::new(host.clone()),
72 },
73 )
74 }
75 }
76}
77
78impl StorageBytes {
79 pub fn is_empty(&self) -> bool {
81 self.len() == 0
82 }
83
84 pub fn len(&self) -> usize {
86 BytesRoot::new(self).len()
87 }
88
89 pub unsafe fn set_len(&mut self, len: usize) {
96 let mut root = BytesRoot::new_mut(self);
97 let old = root.len();
98
99 if (old < 32) == (len < 32) {
101 return root.write_len(len);
102 }
103
104 if (len < 32) && (old >= 32) {
106 root.word = Storage::get_word(root.storage.clone_vm(), *root.storage.base());
107 return root.write_len(len);
108 }
109
110 root.word[31] = 0; Storage::set_word(root.storage.clone_vm(), *root.storage.base(), root.word);
113 root.write_len(len);
114 }
115
116 pub fn push(&mut self, value: u8) {
118 let mut root = BytesRoot::new_mut(self);
119 let index = root.len();
120
121 if index < 31 {
124 root.word[index] = value;
125 unsafe {
126 return root.write_len(index + 1);
127 }
128 }
129
130 if index == 31 {
132 root.word[index] = value;
134 unsafe {
135 Storage::set_word(root.storage.clone_vm(), *root.storage.base(), root.word);
136 return root.write_len(index + 1);
137 }
138 }
139
140 let (slot, offset) = root.index_slot(index);
143 unsafe {
144 Storage::set_uint(
145 root.storage.clone_vm(),
146 slot,
147 offset as usize,
148 U8::from(value),
149 );
150 root.write_len(index + 1);
151 }
152 }
153
154 pub fn pop(&mut self) -> Option<u8> {
158 let mut root = BytesRoot::new_mut(self);
159 let len = root.len();
160 if len == 0 {
161 return None;
162 }
163
164 let index = len - 1;
165
166 if len == 32 {
168 let base = *root.storage.base();
170 root.word = Storage::get_word(root.storage.clone_vm(), base);
171 let byte = root.word[index];
172 unsafe {
173 root.write_len(index);
174 Storage::clear_word(root.storage.clone_vm(), base);
175 }
176 return Some(byte);
177 }
178
179 let byte = root.get(index)?;
180 let clean = index % 32 == 0;
181
182 if len > 32 && clean {
184 unsafe {
185 Storage::clear_word(root.storage.clone_vm(), root.index_slot(len - 1).0);
186 }
187 }
188
189 if len < 32 {
191 root.word[index] = 0;
192 }
193
194 unsafe { root.write_len(index) };
196 Some(byte)
197 }
198
199 pub fn get(&self, index: impl TryInto<usize>) -> Option<u8> {
201 BytesRoot::new(self).get(index)
202 }
203
204 pub fn get_mut(
206 &mut self,
207 index: impl TryInto<usize>,
208 ) -> Option<StorageGuardMut<'_, StorageB8>> {
209 let root = BytesRoot::new_mut(self);
210 let index = index.try_into().ok()?;
211 if index >= root.len() {
212 return None;
213 }
214 let (slot, offset) = root.index_slot(index);
215 let value = unsafe { StorageB8::new(slot, offset, self.clone_vm()) };
216 Some(StorageGuardMut::new(value))
217 }
218
219 pub unsafe fn get_unchecked(&self, index: usize) -> u8 {
225 BytesRoot::new(self).get_unchecked(index)
226 }
227
228 pub fn get_bytes(&self) -> Vec<u8> {
230 let root = BytesRoot::new(self);
231 let len = root.len();
232 let mut bytes = Vec::with_capacity(len);
233
234 if len < 32 {
236 bytes.extend_from_slice(&root.word[..len]);
237 return bytes;
238 }
239 for idx in (0..len).step_by(32) {
241 let (slot, _) = root.index_slot(idx);
242 let word = Storage::get_word(root.storage.clone_vm(), slot);
243 if idx + 32 <= len {
244 bytes.extend(word.0);
246 } else {
247 bytes.extend(&word.0[..len - idx]);
249 };
250 }
251 bytes
252 }
253
254 pub fn set_bytes(&mut self, bytes: impl AsRef<[u8]>) {
256 self.erase();
257 self.extend(bytes.as_ref());
258 }
259
260 fn clone_vm(&self) -> VM {
262 self.__stylus_host.clone()
263 }
264
265 fn base(&self) -> &U256 {
267 self.base
268 .get_or_init(|| crypto::keccak(self.root.to_be_bytes::<32>()).into())
269 }
270}
271
272impl Erase for StorageBytes {
273 fn erase(&mut self) {
274 let root = BytesRoot::new(self);
275 let mut len = root.len() as isize;
276 if len > 31 {
278 while len > 0 {
279 let slot = root.index_slot(len as usize - 1).0;
280 unsafe { Storage::clear_word(root.storage.clone_vm(), slot) };
281 len -= 32;
282 }
283 }
284 unsafe { Storage::clear_word(root.storage.clone_vm(), root.storage.root) };
286 }
287}
288
289impl Extend<u8> for StorageBytes {
290 fn extend<T: IntoIterator<Item = u8>>(&mut self, iter: T) {
291 let mut iter = iter.into_iter().peekable();
292 if iter.peek().is_none() {
293 return;
294 }
295
296 let mut root = BytesRoot::new_mut(self);
297 let mut len = root.len();
298
299 if len < 32 {
301 while len < 32 {
302 if let Some(byte) = iter.next() {
303 root.word[len] = byte;
304 len += 1;
305 } else {
306 break;
307 }
308 }
309 if len < 32 {
311 unsafe {
312 return root.write_len(len);
313 }
314 }
315 unsafe {
317 Storage::set_word(root.storage.clone_vm(), *root.storage.base(), root.word);
318 }
319 }
320 else if len % 32 != 0 {
322 let (slot, _) = root.index_slot(len - 1);
323 let mut word = Storage::get_word(root.storage.clone_vm(), slot);
324 while len % 32 != 0 {
325 if let Some(byte) = iter.next() {
326 word[len % 32] = byte;
327 len += 1;
328 } else {
329 break;
330 }
331 }
332 unsafe {
334 Storage::set_word(root.storage.clone_vm(), slot, word);
335 }
336 if len % 32 != 0 {
338 unsafe {
339 return root.write_len(len);
340 }
341 }
342 }
343
344 let mut slot = *root.storage.base() + U256::from(len / 32);
347 let mut chunk = Vec::with_capacity(32);
348
349 for byte in iter {
351 chunk.push(byte);
352 if chunk.len() == 32 {
353 unsafe {
354 Storage::set_word(root.storage.clone_vm(), slot, B256::from_slice(&chunk));
355 }
356 chunk.clear();
357 len += 32;
358 slot += U256::from(1);
359 }
360 }
361
362 if !chunk.is_empty() {
364 unsafe {
365 Storage::set_word(
366 root.storage.clone_vm(),
367 slot,
368 B256::right_padding_from(&chunk),
369 );
370 }
371 len += chunk.len();
372 }
373
374 unsafe {
375 root.write_len(len);
376 }
377 }
378}
379
380impl<'a> Extend<&'a u8> for StorageBytes {
381 fn extend<T: IntoIterator<Item = &'a u8>>(&mut self, iter: T) {
382 self.extend(iter.into_iter().cloned());
383 }
384}
385
386struct BytesRoot<T> {
388 storage: T,
389 word: B256,
390}
391
392impl<T: Borrow<StorageBytes>> BytesRoot<T> {
393 fn new(storage: T) -> Self {
394 let vm = storage.borrow().clone_vm();
395 let word = Storage::get_word(vm, storage.borrow().root);
396 Self { storage, word }
397 }
398
399 fn len(&self) -> usize {
400 let slot: &[u8] = self.word.as_ref();
402 if slot[31] & 1 == 0 {
403 return (slot[31] / 2) as usize;
404 }
405 let word: U256 = self.word.into();
406 let len = word / U256::from(2);
407 len.try_into().unwrap()
408 }
409
410 pub fn get(&self, index: impl TryInto<usize>) -> Option<u8> {
412 let index = index.try_into().ok()?;
413 if index >= self.len() {
414 return None;
415 }
416 unsafe { Some(self.get_unchecked(index)) }
417 }
418
419 pub unsafe fn get_unchecked(&self, index: usize) -> u8 {
425 let (slot, offset) = self.index_slot(index);
426 unsafe { Storage::get_byte(self.storage.borrow().clone_vm(), slot, offset.into()) }
427 }
428
429 fn index_slot(&self, index: usize) -> (U256, u8) {
431 let storage = self.storage.borrow();
432 let slot = if self.len() >= 32 {
433 storage.base() + U256::from(index / 32)
434 } else {
435 storage.root
436 };
437 (slot, (index % 32) as u8)
438 }
439}
440
441impl<'a> BytesRoot<&'a mut StorageBytes> {
442 fn new_mut(storage: &'a mut StorageBytes) -> Self {
443 let word = Storage::get_word(storage.clone_vm(), storage.root);
444 Self { storage, word }
445 }
446
447 unsafe fn write_len(&mut self, len: usize) {
448 if len < 32 {
449 self.word[31] = len as u8 * 2;
450 } else {
451 self.word = U256::from(len * 2 + 1).into();
452 }
453 Storage::set_word(self.storage.clone_vm(), self.storage.root, self.word);
454 }
455}
456
457pub struct StorageString(pub StorageBytes);
459
460impl StorageType for StorageString {
461 type Wraps<'a>
462 = StorageGuard<'a, StorageString>
463 where
464 Self: 'a;
465 type WrapsMut<'a>
466 = StorageGuardMut<'a, StorageString>
467 where
468 Self: 'a;
469
470 unsafe fn new(slot: U256, offset: u8, host: VM) -> Self {
471 Self(StorageBytes::new(slot, offset, host))
472 }
473
474 fn load<'s>(self) -> Self::Wraps<'s> {
475 StorageGuard::new(self)
476 }
477
478 fn load_mut<'s>(self) -> Self::WrapsMut<'s> {
479 StorageGuardMut::new(self)
480 }
481}
482
483impl HostAccess for StorageString {
484 type Host = VM;
485
486 fn vm(&self) -> &Self::Host {
487 &self.0.__stylus_host
488 }
489}
490
491#[cfg(feature = "stylus-test")]
492impl<T> From<&T> for StorageString
493where
494 T: stylus_core::Host + Clone + 'static,
495{
496 fn from(host: &T) -> Self {
497 unsafe {
498 Self::new(
499 U256::ZERO,
500 0,
501 crate::host::VM {
502 host: alloc::boxed::Box::new(host.clone()),
503 },
504 )
505 }
506 }
507}
508
509impl StorageString {
510 pub fn is_empty(&self) -> bool {
512 self.0.is_empty()
513 }
514
515 pub fn len(&self) -> usize {
517 self.0.len()
518 }
519
520 pub fn push(&mut self, c: char) {
522 for byte in c.to_string().bytes() {
523 self.0.push(byte)
524 }
525 }
526
527 pub fn get_string(&self) -> String {
529 let bytes = self.0.get_bytes();
530 String::from_utf8_lossy(&bytes).into()
531 }
532
533 pub fn set_str(&mut self, text: impl AsRef<str>) {
535 self.erase();
536 self.0.extend(text.as_ref().bytes());
537 }
538}
539
540impl Erase for StorageString {
541 fn erase(&mut self) {
542 self.0.erase()
543 }
544}
545
546impl Extend<char> for StorageString {
547 fn extend<T: IntoIterator<Item = char>>(&mut self, iter: T) {
548 let s = iter.into_iter().collect::<String>();
549 self.0.extend(s.bytes());
550 }
551}
552
553#[cfg(test)]
554mod tests {
555 use alloy_primitives::B256;
556 use stylus_test::vm::*;
557
558 use super::*;
559
560 #[test]
561 fn test_storage_bytes_is_empty() {
562 let test_vm = TestVM::new();
563 let storage = StorageBytes::from(&test_vm);
564
565 let cases = vec![
566 (B256::ZERO, true),
567 (U256::from(5 * 2).into(), false),
568 (U256::from(500 * 2 + 1).into(), false),
569 ];
570
571 for (value, is_empty) in cases {
572 test_vm.set_storage(U256::ZERO, value);
573 assert_eq!(storage.is_empty(), is_empty);
574 }
575 }
576
577 #[test]
578 fn test_storage_bytes_len() {
579 let test_vm = TestVM::new();
580 let storage = StorageBytes::from(&test_vm);
581
582 let cases = vec![
583 (B256::ZERO, 0),
584 (U256::from(5 * 2).into(), 5),
585 (U256::from(500 * 2 + 1).into(), 500),
586 ];
587
588 for (value, len) in cases {
589 test_vm.set_storage(U256::ZERO, value);
590 assert_eq!(storage.len(), len);
591 }
592 }
593
594 #[test]
595 fn test_storage_bytes_write_len() {
596 let test_vm = TestVM::new();
597 let mut storage = StorageBytes::from(&test_vm);
598 let mut root = BytesRoot::new_mut(&mut storage);
599
600 let cases = vec![
601 (0, B256::ZERO),
602 (5, U256::from(5 * 2).into()),
603 (500, U256::from(500 * 2 + 1).into()),
604 ];
605
606 for (len, want) in cases {
607 unsafe {
608 root.write_len(len);
609 }
610 assert_eq!(test_vm.get_storage(U256::ZERO), want);
611 }
612 }
613
614 #[test]
615 fn test_storage_bytes_set_len_small() {
616 let test_vm = TestVM::new();
617 let mut storage = StorageBytes::from(&test_vm);
618
619 let mut value = B256::right_padding_from(&[1, 2, 3, 4, 5]);
620 value[31] = 5 * 2;
621 test_vm.set_storage(U256::ZERO, value);
622
623 unsafe {
624 storage.set_len(4);
625 }
626
627 let mut want = value;
628 want[31] = 4 * 2;
629 assert_eq!(test_vm.get_storage(U256::ZERO), want);
630 }
631
632 #[test]
633 fn test_storage_bytes_set_len_shrinking() {
634 let test_vm = TestVM::new();
635 let mut storage = StorageBytes::from(&test_vm);
636
637 let value: B256 = U256::from(32 * 2 + 1).into();
638 test_vm.set_storage(U256::ZERO, value);
639
640 let value = B256::from([0xfa; 32]);
641 test_vm.set_storage(*storage.base(), value);
642
643 unsafe {
644 storage.set_len(31);
645 }
646
647 let mut want = B256::from([0xfa; 32]);
648 want[31] = 31 * 2;
649 assert_eq!(test_vm.get_storage(U256::ZERO), want);
650 }
651
652 #[test]
653 fn test_storage_bytes_set_len_growing() {
654 let test_vm = TestVM::new();
655 let mut storage = StorageBytes::from(&test_vm);
656
657 let mut value = B256::from([0xfa; 32]);
658 value[31] = 31 * 2;
659 test_vm.set_storage(U256::ZERO, value);
660
661 unsafe {
662 storage.set_len(32);
663 }
664
665 let want: B256 = U256::from(32 * 2 + 1).into();
666 assert_eq!(test_vm.get_storage(U256::ZERO), want);
667 let want = B256::right_padding_from(&[0xfa; 31]);
668 assert_eq!(test_vm.get_storage(*storage.base()), want);
669 }
670
671 #[test]
672 fn test_storage_bytes_push_small() {
673 let test_vm = TestVM::new();
674 let mut storage = StorageBytes::from(&test_vm);
675
676 let mut want = B256::ZERO;
677 for i in 0..31 {
678 storage.push(i);
679 want[i as usize] = i;
680 want[31] = (i + 1) * 2;
681 assert_eq!(test_vm.get_storage(U256::ZERO), want);
682 }
683 }
684
685 #[test]
686 fn test_storage_bytes_push_big() {
687 let test_vm = TestVM::new();
688 let mut storage = StorageBytes::from(&test_vm);
689
690 let value: B256 = U256::from(32 * 2 + 1).into(); test_vm.set_storage(U256::ZERO, value);
692 let value = B256::from([0xfa; 32]); test_vm.set_storage(*storage.base(), value);
694
695 storage.push(0xfa);
696
697 let want: B256 = U256::from(33 * 2 + 1).into();
698 assert_eq!(test_vm.get_storage(U256::ZERO), want);
699 let base = *storage.base();
700 let want = value;
701 assert_eq!(test_vm.get_storage(base), want);
702 let slot = base.saturating_add(U256::from(1));
703 let want = B256::right_padding_from(&[0xfa]);
704 assert_eq!(test_vm.get_storage(slot), want);
705 }
706
707 #[test]
708 fn test_storage_bytes_push_growing() {
709 let test_vm = TestVM::new();
710 let mut storage = StorageBytes::from(&test_vm);
711
712 let mut value = B256::from([0xfa; 32]);
713 value[31] = 31 * 2;
714 test_vm.set_storage(U256::ZERO, value);
715
716 storage.push(0xfa);
717
718 let want: B256 = U256::from(32 * 2 + 1).into();
719 assert_eq!(test_vm.get_storage(U256::ZERO), want);
720 let want = B256::from([0xfa; 32]);
721 assert_eq!(test_vm.get_storage(*storage.base()), want);
722 }
723
724 #[test]
725 fn test_storage_bytes_pop_small() {
726 let test_vm = TestVM::new();
727 let mut storage = StorageBytes::from(&test_vm);
728
729 let mut data: Vec<u8> = (0..31).collect();
730 data.push(31 * 2);
731 test_vm.set_storage(U256::ZERO, B256::from_slice(&data));
732
733 let mut want = B256::from_slice(&data);
734 for i in (0..31).rev() {
735 let popped = storage.pop();
736 assert_eq!(popped, Some(i));
737 want[i as usize] = 0x0;
738 want[31] = i * 2;
739 assert_eq!(test_vm.get_storage(U256::ZERO), want);
740 }
741
742 let value = storage.pop();
743 assert!(value.is_none());
744 assert_eq!(test_vm.get_storage(U256::ZERO), B256::ZERO);
745 }
746
747 #[test]
748 fn test_storage_bytes_pop_big() {
749 let test_vm = TestVM::new();
750 let mut storage = StorageBytes::from(&test_vm);
751
752 let value: B256 = U256::from(64 * 2 + 1).into();
753 test_vm.set_storage(U256::ZERO, value);
754
755 let data: Vec<u8> = (0..64).collect();
756 let base = *storage.base();
757 let after_base = base.saturating_add(U256::from(1));
758 test_vm.set_storage(base, B256::from_slice(&data[0..32]));
759 test_vm.set_storage(after_base, B256::from_slice(&data[32..64]));
760
761 for i in (32..64).rev() {
762 let popped = storage.pop();
763 assert_eq!(popped, Some(i));
764 let want_size: B256 = U256::from(i * 2 + 1).into();
765 assert_eq!(test_vm.get_storage(U256::ZERO), want_size);
766 }
767
768 assert_eq!(test_vm.get_storage(base), B256::from_slice(&data[0..32]));
769 assert_eq!(test_vm.get_storage(after_base), B256::ZERO);
770 }
771
772 #[test]
773 fn test_storage_bytes_pop_shrinking() {
774 let test_vm = TestVM::new();
775 let mut storage = StorageBytes::from(&test_vm);
776
777 let value: B256 = U256::from(32 * 2 + 1).into();
778 test_vm.set_storage(U256::ZERO, value);
779
780 let data: Vec<u8> = (0..32).collect();
781 let base = *storage.base();
782 test_vm.set_storage(base, B256::from_slice(&data[0..32]));
783
784 let popped = storage.pop();
785 assert_eq!(popped, Some(31));
786
787 assert_eq!(test_vm.get_storage(base), B256::ZERO);
788 let mut want = B256::right_padding_from(&data[0..31]);
789 want[31] = 31 * 2;
790 assert_eq!(test_vm.get_storage(U256::ZERO), want);
791 }
792
793 #[test]
794 fn test_storage_bytes_get_small() {
795 let test_vm = TestVM::new();
796 let storage = StorageBytes::from(&test_vm);
797
798 let mut value = (0..31).collect::<Vec<u8>>();
799 value.push(31 * 2);
800 test_vm.set_storage(U256::ZERO, B256::from_slice(&value));
801
802 for i in 0..31 {
803 let got = storage.get(i);
804 assert_eq!(got, Some(i));
805 }
806
807 let got = storage.get(31);
808 assert!(got.is_none());
809 }
810
811 #[test]
812 fn test_storage_bytes_get_big() {
813 let test_vm = TestVM::new();
814 let storage = StorageBytes::from(&test_vm);
815
816 let value: B256 = U256::from(64 * 2 + 1).into();
817 test_vm.set_storage(U256::ZERO, value);
818
819 let data: Vec<u8> = (0..64).collect();
820 let base = *storage.base();
821 test_vm.set_storage(base, B256::from_slice(&data[0..32]));
822 test_vm.set_storage(
823 base.saturating_add(U256::from(1)),
824 B256::from_slice(&data[32..64]),
825 );
826
827 for i in 0..64 {
828 let got = storage.get(i);
829 assert_eq!(got, Some(i));
830 }
831
832 let got = storage.get(64);
833 assert!(got.is_none());
834 }
835
836 #[test]
837 fn test_storage_bytes_get_mut_small() {
838 let test_vm = TestVM::new();
839 let mut storage = StorageBytes::from(&test_vm);
840
841 let mut value = B256::from(&[0xbe; 32]);
842 value[31] = 31 * 2;
843 test_vm.set_storage(U256::ZERO, value);
844
845 let mut want = value;
846 for i in 0..31 {
847 let mut cell = storage.get_mut(i).unwrap();
848 assert_eq!(cell.get(), alloy_primitives::fixed_bytes!("be"));
849 cell.set(alloy_primitives::fixed_bytes!("af"));
850 want[i as usize] = 0xaf;
851 assert_eq!(test_vm.get_storage(U256::ZERO), want);
852 }
853
854 let got = storage.get_mut(31);
855 assert!(got.is_none());
856 }
857
858 #[test]
859 fn test_storage_bytes_get_mut_big() {
860 let test_vm = TestVM::new();
861 let mut storage = StorageBytes::from(&test_vm);
862
863 let value: B256 = U256::from(32 * 2 + 1).into();
864 test_vm.set_storage(U256::ZERO, value);
865 let base = *storage.base();
866 let value = B256::from(&[0xbe; 32]);
867 test_vm.set_storage(base, value);
868
869 let mut want = value;
870 for i in 0..32 {
871 let mut cell = storage.get_mut(i).unwrap();
872 assert_eq!(cell.get(), alloy_primitives::fixed_bytes!("be"));
873 cell.set(alloy_primitives::fixed_bytes!("af"));
874 want[i as usize] = 0xaf;
875 assert_eq!(test_vm.get_storage(base), want);
876 }
877
878 let got = storage.get_mut(32);
879 assert!(got.is_none());
880 }
881
882 #[test]
883 fn test_storage_bytes_get_bytes_small() {
884 let test_vm = TestVM::new();
885 let storage = StorageBytes::from(&test_vm);
886
887 let mut value = (0..31).collect::<Vec<u8>>();
888 value.push(31 * 2);
889 test_vm.set_storage(U256::ZERO, B256::from_slice(&value));
890
891 let got = storage.get_bytes();
892 assert_eq!(&got, &value[0..31]);
893 }
894
895 #[test]
896 fn test_storage_bytes_get_bytes_big() {
897 let test_vm = TestVM::new();
898 let storage = StorageBytes::from(&test_vm);
899
900 let value: B256 = U256::from(64 * 2 + 1).into();
901 test_vm.set_storage(U256::ZERO, value);
902
903 let data: Vec<u8> = (0..64).collect();
904 let base = *storage.base();
905 let after_base = base.saturating_add(U256::from(1));
906 test_vm.set_storage(base, B256::from_slice(&data[0..32]));
907 test_vm.set_storage(after_base, B256::from_slice(&data[32..64]));
908
909 let got = storage.get_bytes();
910 assert_eq!(got, data);
911 }
912
913 #[test]
914 fn test_storage_bytes_set_bytes_small() {
915 let test_vm = TestVM::new();
916 let mut storage = StorageBytes::from(&test_vm);
917
918 let value: B256 = U256::from(64 * 2 + 1).into();
919 test_vm.set_storage(U256::ZERO, value);
920
921 let data: Vec<u8> = (0..64).collect();
922 let base = *storage.base();
923 let after_base = base.saturating_add(U256::from(1));
924 test_vm.set_storage(base, B256::from_slice(&data[0..32]));
925 test_vm.set_storage(after_base, B256::from_slice(&data[32..64]));
926
927 let new_data: Vec<u8> = (100..116).collect();
928 storage.set_bytes(&new_data);
929
930 let mut want = B256::right_padding_from(&new_data);
931 want[31] = new_data.len() as u8 * 2;
932 assert_eq!(test_vm.get_storage(U256::ZERO), want);
933 assert_eq!(test_vm.get_storage(base), B256::ZERO);
934 assert_eq!(test_vm.get_storage(after_base), B256::ZERO);
935 }
936
937 #[test]
938 fn test_storage_bytes_set_bytes_big() {
939 let test_vm = TestVM::new();
940 let mut storage = StorageBytes::from(&test_vm);
941
942 let value: B256 = U256::from(64 * 2 + 1).into();
943 test_vm.set_storage(U256::ZERO, value);
944
945 let data: Vec<u8> = (0..64).collect();
946 let base = *storage.base();
947 let after_base = base.saturating_add(U256::from(1));
948 test_vm.set_storage(base, B256::from_slice(&data[0..32]));
949 test_vm.set_storage(after_base, B256::from_slice(&data[32..64]));
950
951 let new_data: Vec<u8> = (100..132).collect();
952 storage.set_bytes(&new_data);
953
954 let want: B256 = U256::from(32 * 2 + 1).into();
955 assert_eq!(test_vm.get_storage(U256::ZERO), want);
956 assert_eq!(test_vm.get_storage(base), B256::from_slice(&new_data));
957 assert_eq!(test_vm.get_storage(after_base), B256::ZERO);
958 }
959
960 #[test]
961 fn test_storage_bytes_index_slot_small() {
962 let test_vm = TestVM::new();
963 let storage = StorageBytes::from(&test_vm);
964
965 let cases = vec![(0, U256::ZERO, 0), (1, U256::ZERO, 1), (31, U256::ZERO, 31)];
966
967 for (index, slot, offset) in cases {
968 let root = BytesRoot::new(&storage);
969 assert_eq!(root.index_slot(index), (slot, offset));
970 }
971 }
972
973 #[test]
974 fn test_storage_bytes_index_slot_big() {
975 let test_vm = TestVM::new();
976 let storage = StorageBytes::from(&test_vm);
977
978 let value: B256 = U256::from(32 * 2 + 1).into();
979 test_vm.set_storage(U256::ZERO, value);
980
981 let base = *storage.base();
982 let cases = vec![
983 (0, base, 0),
984 (1, base, 1),
985 (31, base, 31),
986 (32, base.saturating_add(U256::from(1)), 0),
987 (33, base.saturating_add(U256::from(1)), 1),
988 (63, base.saturating_add(U256::from(1)), 31),
989 ];
990
991 for (index, slot, offset) in cases {
992 let root = BytesRoot::new(&storage);
993 assert_eq!(root.index_slot(index), (slot, offset));
994 }
995 }
996
997 #[test]
998 fn test_storage_bytes_base() {
999 let test_vm = TestVM::new();
1000 let storage = StorageBytes::from(&test_vm);
1001 let want: U256 = crypto::keccak([0; 32]).into();
1002 assert_eq!(*storage.base(), want);
1003 }
1004
1005 #[test]
1006 fn test_storage_bytes_erase() {
1007 let test_vm = TestVM::new();
1008 let mut storage = StorageBytes::from(&test_vm);
1009
1010 let size = 300;
1011 let value: B256 = U256::from(size * 2 + 1).into();
1012 test_vm.set_storage(U256::ZERO, value);
1013
1014 let n_words = size / 32 + 1;
1015 let base = *storage.base();
1016 for i in 0..n_words {
1017 let word = B256::from([0xfa; 32]);
1018 let slot = base.saturating_add(U256::from(i));
1019 test_vm.set_storage(slot, word);
1020 }
1021
1022 storage.erase();
1023
1024 for i in 0..n_words {
1025 let slot = base.saturating_add(U256::from(i));
1026 assert_eq!(test_vm.get_storage(slot), B256::ZERO);
1027 }
1028 assert_eq!(test_vm.get_storage(U256::ZERO), B256::ZERO);
1029 }
1030
1031 #[test]
1032 fn test_storage_bytes_extend() {
1033 let test_vm = TestVM::new();
1034 let mut storage = StorageBytes::from(&test_vm);
1035
1036 let mut data: Vec<u8> = (0..15).collect();
1037 storage.extend(&data);
1038 let mut want = B256::right_padding_from(&data);
1039 want[31] = data.len() as u8 * 2;
1040 assert_eq!(test_vm.get_storage(U256::ZERO), want);
1041
1042 data.extend(15..30);
1043 storage.extend(15..30);
1044 let mut want = B256::right_padding_from(&data);
1045 want[31] = data.len() as u8 * 2;
1046 assert_eq!(test_vm.get_storage(U256::ZERO), want);
1047
1048 data.extend(30..45);
1049 storage.extend(30..45);
1050 let want: B256 = U256::from(data.len() as u8 * 2 + 1).into();
1051 assert_eq!(test_vm.get_storage(U256::ZERO), want);
1052 let base = *storage.base();
1053 assert_eq!(test_vm.get_storage(base), B256::from_slice(&data[0..32]));
1054 let after_base = base.saturating_add(U256::from(1));
1055 assert_eq!(
1056 test_vm.get_storage(after_base),
1057 B256::right_padding_from(&data[32..45])
1058 );
1059 }
1060}