Skip to main content

stylus_sdk/storage/
bytes.rs

1// Copyright 2022-2024, Offchain Labs, Inc.
2// For licensing, see https://github.com/OffchainLabs/stylus-sdk-rs/blob/main/licenses/COPYRIGHT.md
3
4use 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
16/// Accessor for storage-backed bytes.
17pub 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    /// Returns `true` if the collection contains no elements.
80    pub fn is_empty(&self) -> bool {
81        self.len() == 0
82    }
83
84    /// Gets the number of bytes stored.
85    pub fn len(&self) -> usize {
86        BytesRoot::new(self).len()
87    }
88
89    /// Overwrites the collection's length, moving bytes as needed.
90    ///
91    /// # Safety
92    ///
93    /// May populate the vector with junk bytes from prior dirty operations.
94    /// Note that [`StorageBytes`] has unlimited capacity, so all lengths are valid.
95    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 representation hasn't changed, just update the length
100        if (old < 32) == (len < 32) {
101            return root.write_len(len);
102        }
103
104        // if shrinking, pull data in
105        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        // if growing, push data out
111        root.word[31] = 0; // clear len byte
112        Storage::set_word(root.storage.clone_vm(), *root.storage.base(), root.word);
113        root.write_len(len);
114    }
115
116    /// Adds a byte to the end.
117    pub fn push(&mut self, value: u8) {
118        let mut root = BytesRoot::new_mut(self);
119        let index = root.len();
120
121        // still short representation after adding a byte
122        // add the byte and update length
123        if index < 31 {
124            root.word[index] = value;
125            unsafe {
126                return root.write_len(index + 1);
127            }
128        }
129
130        // convert to multi-word representation
131        if index == 31 {
132            // copy content over (len byte will be overwritten)
133            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        // already long representation
141        // add the new byte and update length
142        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    /// Removes and returns the last byte, if it exists.
155    /// As an optimization, underlying storage slots are only erased when all bytes in
156    /// a given word are freed when in the multi-word representation.
157    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        // convert to single-word representation
167        if len == 32 {
168            // copy content over
169            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        // clear distant word
183        if len > 32 && clean {
184            unsafe {
185                Storage::clear_word(root.storage.clone_vm(), root.index_slot(len - 1).0);
186            }
187        }
188
189        // clear the value
190        if len < 32 {
191            root.word[index] = 0;
192        }
193
194        // set the new length
195        unsafe { root.write_len(index) };
196        Some(byte)
197    }
198
199    /// Gets the byte at the given index, if it exists.
200    pub fn get(&self, index: impl TryInto<usize>) -> Option<u8> {
201        BytesRoot::new(self).get(index)
202    }
203
204    /// Gets a mutable accessor to the byte at the given index, if it exists.
205    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    /// Gets the byte at the given index, even if beyond the collection.
220    ///
221    /// # Safety
222    ///
223    /// UB if index is out of bounds.
224    pub unsafe fn get_unchecked(&self, index: usize) -> u8 {
225        BytesRoot::new(self).get_unchecked(index)
226    }
227
228    /// Gets the full contents of the collection.
229    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        // for short representation, use appropriate number of bytes from root
235        if len < 32 {
236            bytes.extend_from_slice(&root.word[..len]);
237            return bytes;
238        }
239        // for long representation, read one word at a time from storage
240        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                // entire word is part of the byte array
245                bytes.extend(word.0);
246            } else {
247                // for the last word, only get remaining bytes
248                bytes.extend(&word.0[..len - idx]);
249            };
250        }
251        bytes
252    }
253
254    /// Overwrites the contents of the collection, erasing what was previously stored.
255    pub fn set_bytes(&mut self, bytes: impl AsRef<[u8]>) {
256        self.erase();
257        self.extend(bytes.as_ref());
258    }
259
260    /// Returns a copy of VM.
261    fn clone_vm(&self) -> VM {
262        self.__stylus_host.clone()
263    }
264
265    /// Determines where in storage indices start. Could be made `const` in the future.
266    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        // clear any slots used in long storage
277        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        // set length and data in root storage to zero
285        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 storage is small, grow it until it reaches 32 bytes
300        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 storage is still small, store short representation
310            if len < 32 {
311                unsafe {
312                    return root.write_len(len);
313                }
314            }
315            // if len reaches 32 bytes, grow into big representation
316            unsafe {
317                Storage::set_word(root.storage.clone_vm(), *root.storage.base(), root.word);
318            }
319        }
320        // we want to work with word-aligned chunks, fill in first chunk to get there
321        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            // write the word we just filled in
333            unsafe {
334                Storage::set_word(root.storage.clone_vm(), slot, word);
335            }
336            // stop if iter is complete.
337            if len % 32 != 0 {
338                unsafe {
339                    return root.write_len(len);
340                }
341            }
342        }
343
344        // get the slot where we will write the first chunk; we can't use root.get_slot because len
345        // is not set
346        let mut slot = *root.storage.base() + U256::from(len / 32);
347        let mut chunk = Vec::with_capacity(32);
348
349        // write to storage, a word at a time
350        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        // write remaining chunk
363        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
386/// Contains methods to manipulate the root storage slot of StorageBytes.
387struct 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        // check if the data is short
401        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    /// Gets the byte at the given index, if it exists.
411    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    /// Gets the byte at the given index, even if beyond the collection.
420    ///
421    /// # Safety
422    ///
423    /// UB if index is out of bounds.
424    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    /// Determines the slot and offset for the element at an index.
430    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
457/// Accessor for storage-backed bytes
458pub 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    /// Returns `true` if the collection contains no elements.
511    pub fn is_empty(&self) -> bool {
512        self.0.is_empty()
513    }
514
515    /// Gets the number of bytes stored.
516    pub fn len(&self) -> usize {
517        self.0.len()
518    }
519
520    /// Adds a char to the end.
521    pub fn push(&mut self, c: char) {
522        for byte in c.to_string().bytes() {
523            self.0.push(byte)
524        }
525    }
526
527    /// Gets the underlying [`String`], ignoring any invalid data.
528    pub fn get_string(&self) -> String {
529        let bytes = self.0.get_bytes();
530        String::from_utf8_lossy(&bytes).into()
531    }
532
533    /// Overwrites the underlying [`String`], erasing what was previously stored.
534    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(); // size
691        test_vm.set_storage(U256::ZERO, value);
692        let value = B256::from([0xfa; 32]); // contents
693        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}