concordium_std/
impls.rs

1#[cfg(feature = "p7")]
2use crate::vec;
3use crate::{
4    cell::UnsafeCell,
5    convert::{self, TryInto},
6    fmt,
7    marker::PhantomData,
8    mem::{self, MaybeUninit},
9    num,
10    num::NonZeroU32,
11    prims, state_btree,
12    traits::*,
13    types::*,
14    vec::Vec,
15    String,
16};
17pub(crate) use concordium_contracts_common::*;
18
19/// Mapped to i32::MIN + 1.
20impl convert::From<()> for Reject {
21    #[inline(always)]
22    fn from(_: ()) -> Self { unsafe { num::NonZeroI32::new_unchecked(i32::MIN + 1) }.into() }
23}
24
25/// Mapped to i32::MIN + 2.
26impl convert::From<ParseError> for Reject {
27    #[inline(always)]
28    fn from(_: ParseError) -> Self {
29        unsafe { num::NonZeroI32::new_unchecked(i32::MIN + 2) }.into()
30    }
31}
32
33/// Full is mapped to i32::MIN + 3,
34/// Malformed is mapped to i32::MIN + 4.
35impl From<LogError> for Reject {
36    #[inline(always)]
37    fn from(le: LogError) -> Self {
38        match le {
39            LogError::Full => unsafe { crate::num::NonZeroI32::new_unchecked(i32::MIN + 3) }.into(),
40            LogError::Malformed => {
41                unsafe { crate::num::NonZeroI32::new_unchecked(i32::MIN + 4) }.into()
42            }
43        }
44    }
45}
46
47/// MissingInitPrefix is mapped to i32::MIN + 5,
48/// TooLong to i32::MIN + 6,
49/// ContainsDot to i32::MIN + 9, and
50/// InvalidCharacters to i32::MIN + 10.
51impl From<NewContractNameError> for Reject {
52    fn from(nre: NewContractNameError) -> Self {
53        match nre {
54            NewContractNameError::MissingInitPrefix => unsafe {
55                crate::num::NonZeroI32::new_unchecked(i32::MIN + 5).into()
56            },
57            NewContractNameError::TooLong => unsafe {
58                crate::num::NonZeroI32::new_unchecked(i32::MIN + 6).into()
59            },
60            NewContractNameError::ContainsDot => unsafe {
61                crate::num::NonZeroI32::new_unchecked(i32::MIN + 9).into()
62            },
63            NewContractNameError::InvalidCharacters => unsafe {
64                crate::num::NonZeroI32::new_unchecked(i32::MIN + 10).into()
65            },
66        }
67    }
68}
69
70/// MissingDotSeparator is mapped to i32::MIN + 7,
71/// TooLong to i32::MIN + 8, and
72/// InvalidCharacters to i32::MIN + 11.
73impl From<NewReceiveNameError> for Reject {
74    fn from(nre: NewReceiveNameError) -> Self {
75        match nre {
76            NewReceiveNameError::MissingDotSeparator => unsafe {
77                crate::num::NonZeroI32::new_unchecked(i32::MIN + 7).into()
78            },
79            NewReceiveNameError::TooLong => unsafe {
80                crate::num::NonZeroI32::new_unchecked(i32::MIN + 8).into()
81            },
82            NewReceiveNameError::InvalidCharacters => unsafe {
83                crate::num::NonZeroI32::new_unchecked(i32::MIN + 11).into()
84            },
85        }
86    }
87}
88
89/// The error code is i32::MIN + 12.
90impl From<NotPayableError> for Reject {
91    #[inline(always)]
92    fn from(_: NotPayableError) -> Self {
93        unsafe { crate::num::NonZeroI32::new_unchecked(i32::MIN + 12) }.into()
94    }
95}
96
97/// AmountTooLarge is i32::MIN + 13,
98/// MissingAccount is i32::MIN + 14.
99impl From<TransferError> for Reject {
100    #[inline(always)]
101    fn from(te: TransferError) -> Self {
102        match te {
103            TransferError::AmountTooLarge => unsafe {
104                crate::num::NonZeroI32::new_unchecked(i32::MIN + 13).into()
105            },
106            TransferError::MissingAccount => unsafe {
107                crate::num::NonZeroI32::new_unchecked(i32::MIN + 14).into()
108            },
109        }
110    }
111}
112
113/// AmountTooLarge is i32::MIN + 15,
114/// MissingAccount is i32::MIN + 16,
115/// MissingContract is i32::MIN + 17,
116/// MissingEntrypoint is i32::MIN + 18,
117/// MessageFailed is i32::MIN + 19,
118/// LogicReject is i32::MIN + 20,
119/// Trap is i32::MIN + 21.
120impl<T> From<CallContractError<T>> for Reject {
121    #[inline(always)]
122    fn from(cce: CallContractError<T>) -> Self {
123        match cce {
124            CallContractError::AmountTooLarge => unsafe {
125                crate::num::NonZeroI32::new_unchecked(i32::MIN + 15).into()
126            },
127            CallContractError::MissingAccount => unsafe {
128                crate::num::NonZeroI32::new_unchecked(i32::MIN + 16).into()
129            },
130            CallContractError::MissingContract => unsafe {
131                crate::num::NonZeroI32::new_unchecked(i32::MIN + 17).into()
132            },
133            CallContractError::MissingEntrypoint => unsafe {
134                crate::num::NonZeroI32::new_unchecked(i32::MIN + 18).into()
135            },
136            CallContractError::MessageFailed => unsafe {
137                crate::num::NonZeroI32::new_unchecked(i32::MIN + 19).into()
138            },
139            CallContractError::LogicReject {
140                ..
141            } => unsafe { crate::num::NonZeroI32::new_unchecked(i32::MIN + 20).into() },
142            CallContractError::Trap => unsafe {
143                crate::num::NonZeroI32::new_unchecked(i32::MIN + 21).into()
144            },
145        }
146    }
147}
148
149/// MissingModule is i32::MIN + 22,
150/// MissingContract is i32::MIN + 23,
151/// UnsupportedModuleVersion is i32::MIN + 24.
152impl From<UpgradeError> for Reject {
153    #[inline(always)]
154    fn from(te: UpgradeError) -> Self {
155        match te {
156            UpgradeError::MissingModule => unsafe {
157                crate::num::NonZeroI32::new_unchecked(i32::MIN + 22).into()
158            },
159            UpgradeError::MissingContract => unsafe {
160                crate::num::NonZeroI32::new_unchecked(i32::MIN + 23).into()
161            },
162            UpgradeError::UnsupportedModuleVersion => unsafe {
163                crate::num::NonZeroI32::new_unchecked(i32::MIN + 24).into()
164            },
165        }
166    }
167}
168
169/// Query account balance error missing account is i32::MIN + 25.
170impl From<QueryAccountBalanceError> for Reject {
171    #[inline(always)]
172    fn from(_: QueryAccountBalanceError) -> Self {
173        unsafe { crate::num::NonZeroI32::new_unchecked(i32::MIN + 25).into() }
174    }
175}
176
177/// Query contract balance error missing contract is i32::MIN + 26.
178impl From<QueryContractBalanceError> for Reject {
179    #[inline(always)]
180    fn from(_: QueryContractBalanceError) -> Self {
181        unsafe { crate::num::NonZeroI32::new_unchecked(i32::MIN + 26).into() }
182    }
183}
184
185/// Return values are intended to be produced by writing to the
186/// [ExternReturnValue] buffer, either in a high-level interface via
187/// serialization, or in a low-level interface by manually using the [Write]
188/// trait's interface.
189impl Write for ExternReturnValue {
190    type Err = ();
191
192    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Err> {
193        let len: u32 = {
194            match buf.len().try_into() {
195                Ok(v) => v,
196                _ => return Err(()),
197            }
198        };
199        if self.current_position.checked_add(len).is_none() {
200            return Err(());
201        }
202        let num_bytes = unsafe { prims::write_output(buf.as_ptr(), len, self.current_position) };
203        self.current_position += num_bytes; // safe because of check above that len + pos is small enough
204        Ok(num_bytes as usize)
205    }
206}
207
208impl ExternReturnValue {
209    #[inline(always)]
210    /// Create a return value cursor that starts at the beginning.
211    /// Note that there is a single return value per contract invocation, so
212    /// multiple calls to open will give access to writing the same return
213    /// value. Thus this function should only be used once per contract
214    /// invocation.
215    pub fn open() -> Self {
216        Self {
217            current_position: 0,
218        }
219    }
220}
221
222impl StateEntry {
223    /// Open a new state entry with its `current_position` set to `0`.
224    pub(crate) fn open(state_entry_id: StateEntryId, key: Vec<u8>) -> Self {
225        Self {
226            state_entry_id,
227            key,
228            current_position: 0,
229        }
230    }
231}
232
233impl HasStateEntry for StateEntry {
234    type Error = ();
235    type StateEntryData = ();
236    type StateEntryKey = ();
237
238    #[inline(always)]
239    fn move_to_start(&mut self) { self.current_position = 0; }
240
241    #[inline(always)]
242    fn size(&self) -> Result<u32, Self::Error> {
243        let res = unsafe { prims::state_entry_size(self.state_entry_id) };
244        match res {
245            u32::MAX => Err(()),
246            _ => Ok(res),
247        }
248    }
249
250    fn truncate(&mut self, new_size: u32) -> Result<(), Self::Error> {
251        let cur_size = self.size()?;
252        if cur_size > new_size {
253            self.resize(new_size)?;
254        }
255        Ok(())
256    }
257
258    fn get_key(&self) -> &[u8] { &self.key }
259
260    fn resize(&mut self, new_size: u32) -> Result<(), Self::Error> {
261        let res = unsafe { prims::state_entry_resize(self.state_entry_id, new_size) };
262        match res {
263            1 => {
264                if self.current_position > new_size {
265                    self.current_position = new_size;
266                }
267                Ok(())
268            }
269            _ => Err(()),
270        }
271    }
272}
273
274impl Seek for StateEntry {
275    type Err = ();
276
277    #[inline]
278    // Make sure the inline is OK. This is a relatively big function, but once
279    // specialized to one of the branches it should benefit from inlining.
280    fn seek(&mut self, pos: SeekFrom) -> Result<u32, Self::Err> {
281        use SeekFrom::*;
282        let end = self.size()?;
283        match pos {
284            Start(offset) => {
285                if offset <= end {
286                    self.current_position = offset;
287                    Ok(offset)
288                } else {
289                    Err(())
290                }
291            }
292            End(delta) => {
293                if delta > 0 {
294                    Err(()) // cannot seek beyond the end
295                } else {
296                    // due to two's complement representation of values we do not have to
297                    // distinguish on whether we go forward or backwards. Reinterpreting the bits
298                    // and adding unsigned values is the same as subtracting the
299                    // absolute value.
300                    let new_offset = end.wrapping_add(delta as u32);
301                    if new_offset <= end {
302                        self.current_position = new_offset;
303                        Ok(new_offset)
304                    } else {
305                        Err(())
306                    }
307                }
308            }
309            Current(delta) => {
310                // due to two's complement representation of values we do not have to
311                // distinguish on whether we go forward or backwards.
312                let new_offset = self.current_position + delta as u32;
313                if new_offset <= end {
314                    self.current_position = new_offset;
315                    Ok(new_offset)
316                } else {
317                    Err(())
318                }
319            }
320        }
321    }
322
323    #[inline(always)]
324    fn cursor_position(&self) -> u32 { self.current_position }
325}
326
327impl Read for StateEntry {
328    fn read(&mut self, buf: &mut [u8]) -> ParseResult<usize> {
329        let len: u32 = buf.len().try_into().map_err(|_| ParseError::default())?;
330        let num_read = unsafe {
331            prims::state_entry_read(
332                self.state_entry_id,
333                buf.as_mut_ptr(),
334                len,
335                self.current_position,
336            )
337        };
338        if num_read == u32::MAX {
339            return Err(ParseError::default()); // Entry did not exist.
340        }
341        self.current_position += num_read;
342        Ok(num_read as usize)
343    }
344
345    /// Read a `u64` in little-endian format. This is optimized to not
346    /// initialize a dummy value before calling an external function.
347    fn read_u64(&mut self) -> ParseResult<u64> {
348        let mut bytes: MaybeUninit<[u8; 8]> = MaybeUninit::uninit();
349        let num_read = unsafe {
350            prims::state_entry_read(
351                self.state_entry_id,
352                bytes.as_mut_ptr() as *mut u8,
353                8,
354                self.current_position,
355            )
356        };
357        if num_read == u32::MAX {
358            return Err(ParseError::default()); // Entry did not exist.
359        }
360        self.current_position += num_read;
361        if num_read == 8 {
362            unsafe { Ok(u64::from_le_bytes(bytes.assume_init())) }
363        } else {
364            Err(ParseError::default())
365        }
366    }
367
368    /// Read a `u32` in little-endian format. This is optimized to not
369    /// initialize a dummy value before calling an external function.
370    fn read_u32(&mut self) -> ParseResult<u32> {
371        let mut bytes: MaybeUninit<[u8; 4]> = MaybeUninit::uninit();
372        let num_read = unsafe {
373            prims::state_entry_read(
374                self.state_entry_id,
375                bytes.as_mut_ptr() as *mut u8,
376                4,
377                self.current_position,
378            )
379        };
380        if num_read == u32::MAX {
381            return Err(ParseError::default()); // Entry did not exist.
382        }
383        self.current_position += num_read;
384        if num_read == 4 {
385            unsafe { Ok(u32::from_le_bytes(bytes.assume_init())) }
386        } else {
387            Err(ParseError::default())
388        }
389    }
390
391    /// Read a `u8` in little-endian format. This is optimized to not
392    /// initialize a dummy value before calling an external function.
393    fn read_u8(&mut self) -> ParseResult<u8> {
394        let mut bytes: MaybeUninit<[u8; 1]> = MaybeUninit::uninit();
395        let num_read = unsafe {
396            prims::state_entry_read(
397                self.state_entry_id,
398                bytes.as_mut_ptr() as *mut u8,
399                1,
400                self.current_position,
401            )
402        };
403        if num_read == u32::MAX {
404            return Err(ParseError::default()); // Entry did not exist.
405        }
406        self.current_position += num_read;
407        if num_read == 1 {
408            unsafe { Ok(bytes.assume_init()[0]) }
409        } else {
410            Err(ParseError::default())
411        }
412    }
413}
414
415impl Write for StateEntry {
416    type Err = ();
417
418    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Err> {
419        let len: u32 = {
420            match buf.len().try_into() {
421                Ok(v) => v,
422                _ => return Err(()),
423            }
424        };
425        if self.current_position.checked_add(len).is_none() {
426            return Err(());
427        }
428        let num_bytes = unsafe {
429            prims::state_entry_write(self.state_entry_id, buf.as_ptr(), len, self.current_position)
430        };
431        if num_bytes == u32::MAX {
432            return Err(()); // Entry did not exist.
433        }
434        self.current_position += num_bytes; // safe because of check above that len + pos is small enough
435        Ok(num_bytes as usize)
436    }
437}
438
439impl<StateApi: HasStateApi> VacantEntryRaw<StateApi> {
440    /// Create a new `VacantEntryRaw`.
441    pub(crate) fn new(key: Key, state_api: StateApi) -> Self {
442        Self {
443            key,
444            state_api,
445        }
446    }
447
448    /// Gets a reference to the key that would be used when inserting a value
449    /// through the `VacantEntryRaw`.
450    #[inline(always)]
451    pub fn key(&self) -> &[u8] { &self.key }
452
453    /// Sets the value of the entry with the [`VacantEntryRaw`’s](Self) key.
454    pub fn insert_raw(mut self, value: &[u8]) -> Result<StateApi::EntryType, StateError> {
455        let mut entry = self.state_api.create_entry(&self.key)?;
456        entry.write_all(value).unwrap_abort(); // Writing to state cannot fail.
457        entry.move_to_start(); // Reset cursor.
458        Ok(entry)
459    }
460
461    /// Sets the value of the entry with the `VacantEntryRaw`’s key.
462    /// This differs from
463    /// [`insert_raw`](Self::insert_raw) in that it automatically serializes
464    /// the provided value. [`insert`](Self::insert) should be preferred
465    /// for values that can be directly converted to byte arrays, e.g., any
466    /// value that implements [`AsRef<[u8]>`](AsRef).
467    pub fn insert<V: Serial>(mut self, value: &V) -> Result<StateApi::EntryType, StateError> {
468        let mut entry = self.state_api.create_entry(&self.key)?;
469        // Writing to state cannot fail unless the value is too large (more than 2^31
470        // bytes). We can't do much about that.
471        value.serial(&mut entry).unwrap_abort();
472        entry.move_to_start(); // Reset cursor.
473        Ok(entry)
474    }
475}
476
477impl<StateApi: HasStateApi> OccupiedEntryRaw<StateApi> {
478    /// Create a new `OccupiedEntryRaw`.
479    pub(crate) fn new(state_entry: StateApi::EntryType) -> Self {
480        Self {
481            state_entry,
482        }
483    }
484
485    /// Gets a reference to the key that would be used when inserting a value
486    /// through the `OccupiedEntryRaw`.
487    #[inline(always)]
488    pub fn key(&self) -> &[u8] { self.state_entry.get_key() }
489
490    /// Gets a reference to the [`HasStateEntry`] type in the entry.
491    #[inline(always)]
492    pub fn get_ref(&self) -> &StateApi::EntryType { &self.state_entry }
493
494    /// Converts the entry into its [`HasStateEntry`] type.
495    ///
496    /// If you need multiple mutable references to the `OccupiedEntryRaw`, see
497    /// [`get_mut`][Self::get_mut].
498    #[inline(always)]
499    pub fn get(self) -> StateApi::EntryType { self.state_entry }
500
501    /// Gets a mutable reference to the [`HasStateEntry`] type in the entry.
502    ///
503    /// If you need access to a [`HasStateEntry`], which can outlive the
504    /// `OccupiedEntryRaw`, see [`get`][Self::get].
505    #[inline(always)]
506    pub fn get_mut(&mut self) -> &mut StateApi::EntryType { &mut self.state_entry }
507
508    /// Sets the value of the entry with the `OccupiedEntryRaw`'s key.
509    pub fn insert_raw(&mut self, value: &[u8]) {
510        self.state_entry.move_to_start();
511        self.state_entry.write_all(value).unwrap_abort();
512
513        // Truncate any data leftover from previous value.
514        self.state_entry.truncate(value.len() as u32).unwrap_abort();
515    }
516
517    /// Sets the value of the entry with the [`OccupiedEntryRaw`'s](Self) key.
518    /// This differs from [`insert_raw`](Self::insert_raw) in that it
519    /// automatically serializes the value. The [`insert`](Self::insert)
520    /// should be preferred if the value is already a byte array.
521    pub fn insert<V: Serial>(&mut self, value: &V) {
522        // Truncate so that no data is leftover from previous value.
523        self.state_entry.truncate(0).unwrap_abort();
524        self.state_entry.move_to_start();
525        value.serial(&mut self.state_entry).unwrap_abort()
526    }
527}
528
529impl<StateApi: HasStateApi> EntryRaw<StateApi> {
530    /// Ensures a value is in the entry by inserting the default if empty, and
531    /// returns the [`HasStateEntry`] type for the entry.
532    pub fn or_insert_raw(self, default: &[u8]) -> Result<StateApi::EntryType, StateError> {
533        match self {
534            EntryRaw::Vacant(vac) => vac.insert_raw(default),
535            EntryRaw::Occupied(occ) => Ok(occ.get()),
536        }
537    }
538
539    /// Ensures a value is in the entry by inserting the default if empty, and
540    /// returns the [`HasStateEntry`] type. This differs from
541    /// [`or_insert_raw`](Self::or_insert_raw) in that it automatically
542    /// serializes the provided value. [`or_insert`](Self::or_insert) should
543    /// be preferred for values that can be directly converted to byte
544    /// arrays, e.g., any value that implements [`AsRef<[u8]>`](AsRef).
545    pub fn or_insert<V: Serial>(self, default: &V) -> StateApi::EntryType {
546        match self {
547            EntryRaw::Vacant(vac) => vac.insert(default).unwrap_abort(),
548            EntryRaw::Occupied(occ) => occ.get(),
549        }
550    }
551
552    /// Returns a reference to this entry's key.
553    pub fn key(&self) -> &[u8] {
554        match self {
555            EntryRaw::Vacant(vac) => vac.key(),
556            EntryRaw::Occupied(occ) => occ.key(),
557        }
558    }
559}
560
561impl<'a, K, V, StateApi> VacantEntry<'a, K, V, StateApi>
562where
563    K: Serial,
564    V: Serial,
565    StateApi: HasStateApi,
566{
567    /// Create a new `VacantEntry`.
568    pub(crate) fn new(key: K, key_bytes: Vec<u8>, state_api: StateApi) -> Self {
569        Self {
570            key,
571            key_bytes,
572            state_api,
573            _lifetime_marker: PhantomData,
574        }
575    }
576
577    /// Get a reference to the `VacantEntry`'s key.
578    #[inline(always)]
579    pub fn key(&self) -> &K { &self.key }
580
581    /// Take ownership of the key.
582    #[inline(always)]
583    pub fn into_key(self) -> K { self.key }
584
585    /// Sets the value of the entry with the `VacantEntry`'s key.
586    pub fn insert(mut self, value: V) -> OccupiedEntry<'a, K, V, StateApi> {
587        // Writing to state cannot fail.
588        let mut state_entry = self.state_api.create_entry(&self.key_bytes).unwrap_abort();
589        value.serial(&mut state_entry).unwrap_abort();
590        state_entry.move_to_start(); // Reset cursor.
591        OccupiedEntry {
592            key: self.key,
593            value,
594            modified: false,
595            state_entry,
596            _lifetime_marker: self._lifetime_marker,
597        }
598    }
599}
600
601impl<'a, K, V, StateApi> OccupiedEntry<'a, K, V, StateApi>
602where
603    K: Serial,
604    V: Serial,
605    StateApi: HasStateApi,
606{
607    /// Create a new `OccupiedEntry`.
608    pub(crate) fn new(key: K, value: V, state_entry: StateApi::EntryType) -> Self {
609        Self {
610            key,
611            value,
612            modified: false,
613            state_entry,
614            _lifetime_marker: PhantomData,
615        }
616    }
617
618    /// Get a reference to the key that is associated with this entry.
619    #[inline(always)]
620    pub fn key(&self) -> &K { &self.key }
621
622    /// Get an immutable reference to the value contained in this entry.
623    #[inline(always)]
624    pub fn get_ref(&self) -> &V { &self.value }
625
626    /// Modify the value in the entry, and possibly return
627    /// some information.
628    #[inline]
629    pub fn modify<F, A>(&mut self, f: F) -> A
630    where
631        // NB: This closure cannot return a reference to V. The reason for this is
632        // that the type of the closure is really `for<'b>FnOnce<&'b mut V> -> A`.
633        // In particular, the lifetime of the reference the closure gets is not tied directly to the
634        // lifetime of `Self`.
635        F: FnOnce(&mut V) -> A, {
636        let res = f(&mut self.value);
637        self.store_value();
638        res
639    }
640
641    /// Like [`modify`](Self::modify), but allows the closure to signal failure,
642    /// aborting the update.
643    pub fn try_modify<F, A, E>(&mut self, f: F) -> Result<A, E>
644    where
645        F: FnOnce(&mut V) -> Result<A, E>, {
646        let res = f(&mut self.value)?;
647        self.store_value();
648        Ok(res)
649    }
650}
651
652impl<'a, K, V, StateApi> OccupiedEntry<'a, K, V, StateApi>
653where
654    V: Serial,
655    StateApi: HasStateApi,
656{
657    pub(crate) fn store_value(&mut self) {
658        // First truncate it back to 0. This is not ideal in some cases, since
659        // it is a needless call.
660        // An alternative would be to first write to a temporary buffer,
661        // resize the entry to the size of that buffer, and then copy that buffer in.
662        // That has the disadvantage of allocating an intermediate buffer.
663        self.state_entry.truncate(0).unwrap_abort();
664        // If we did not manage to serialize we just abort. This can only happen
665        // if (1) one of the serial implementations raises an error, which it should not
666        // in normal circumstances or (2) we have run of out of space to write
667        // the entry. However the limit to entry size is 2^31 so this
668        // will not happen in practice.
669        self.value.serial(&mut self.state_entry).unwrap_abort();
670    }
671}
672
673impl<'a, K, V, StateApi> Entry<'a, K, V, StateApi>
674where
675    K: Serial,
676    V: Serial,
677    StateApi: HasStateApi,
678{
679    /// Return whether the entry is vacant.
680    #[inline(always)]
681    pub fn is_vacant(&self) -> bool { matches!(self, Entry::Vacant(_)) }
682
683    /// Return whether the entry is occupied.
684    #[inline(always)]
685    pub fn is_occupied(&self) -> bool { matches!(self, Entry::Occupied(_)) }
686
687    /// If the entry is [`Occupied`](Entry::Occupied) return `Ok`. Otherwise
688    /// return the supplied error.
689    #[inline]
690    pub fn occupied_or<E>(self, e: E) -> Result<OccupiedEntry<'a, K, V, StateApi>, E> {
691        match self {
692            Entry::Vacant(_) => Err(e),
693            Entry::Occupied(oe) => Ok(oe),
694        }
695    }
696
697    /// If the entry is [`Vacant`](Entry::Vacant) return `Ok`. Otherwise return
698    /// the supplied error.
699    #[inline]
700    pub fn vacant_or<E>(self, e: E) -> Result<VacantEntry<'a, K, V, StateApi>, E> {
701        match self {
702            Entry::Vacant(vac) => Ok(vac),
703            Entry::Occupied(_) => Err(e),
704        }
705    }
706
707    /// Ensure a value is in the entry by inserting the provided value if the
708    /// entry is vacant.
709    pub fn or_insert(self, value: V) -> OccupiedEntry<'a, K, V, StateApi> {
710        match self {
711            Entry::Vacant(vac) => vac.insert(value),
712            Entry::Occupied(oe) => oe,
713        }
714    }
715
716    /// Ensures a value is in the entry by inserting the result of the default
717    /// function if empty.
718    pub fn or_insert_with<F>(self, default: F) -> OccupiedEntry<'a, K, V, StateApi>
719    where
720        F: FnOnce() -> V, {
721        match self {
722            Entry::Vacant(vac) => vac.insert(default()),
723            Entry::Occupied(oe) => oe,
724        }
725    }
726
727    /// If the entry is occupied apply the given function to its contents.
728    /// If the function returns an error the contents are not updated.
729    /// **If the supplied function returns an error then it should not modify
730    /// the given value. If it does so than the map will become
731    /// inconsistent.** If the entry is vacant no changes are made.
732    pub fn and_try_modify<F, E>(mut self, f: F) -> Result<Entry<'a, K, V, StateApi>, E>
733    where
734        F: FnOnce(&mut V) -> Result<(), E>, {
735        if let Entry::Occupied(ref mut occ) = self {
736            occ.try_modify(f)?;
737        }
738        Ok(self)
739    }
740
741    /// If the entry is occupied apply the given function to its contents.
742    /// If the entry is vacant no changes are made.
743    pub fn and_modify<F>(mut self, f: F) -> Entry<'a, K, V, StateApi>
744    where
745        F: FnOnce(&mut V), {
746        if let Entry::Occupied(ref mut occ) = self {
747            occ.modify(f);
748        }
749        self
750    }
751
752    /// Return a reference to this entry's key.
753    pub fn key(&self) -> &K {
754        match self {
755            Entry::Vacant(vac) => vac.key(),
756            Entry::Occupied(occ) => occ.key(),
757        }
758    }
759}
760
761impl<'a, K, V, StateApi> Entry<'a, K, V, StateApi>
762where
763    K: Serial,
764    V: Serial + Default,
765    StateApi: HasStateApi,
766{
767    /// Ensures a value is in the entry by inserting the default value if empty.
768    #[allow(clippy::unwrap_or_default)]
769    pub fn or_default(self) -> OccupiedEntry<'a, K, V, StateApi> {
770        self.or_insert_with(Default::default)
771    }
772}
773
774/// The (i.e., location in the contract state trie) at which the
775/// "allocator"/state builder stores "next location". The values stored at this
776/// location are 64-bit integers.
777const NEXT_ITEM_PREFIX_KEY: [u8; 8] = 0u64.to_le_bytes();
778/// Initial location to store in [NEXT_ITEM_PREFIX_KEY]. For example, the
779/// initial call to "new_state_box" will allocate the box at this location.
780pub(crate) const INITIAL_NEXT_ITEM_PREFIX: [u8; 8] = 2u64.to_le_bytes();
781
782impl HasStateApi for ExternStateApi {
783    type EntryType = StateEntry;
784    type IterType = ExternStateIter;
785
786    fn create_entry(&mut self, key: &[u8]) -> Result<Self::EntryType, StateError> {
787        let key_start = key.as_ptr();
788        let key_len = key.len() as u32; // Wasm usize == 32bit.
789        let entry_id = unsafe { prims::state_create_entry(key_start, key_len) };
790        if entry_id == u64::MAX {
791            return Err(StateError::SubtreeLocked);
792        }
793        Ok(StateEntry::open(entry_id, key.to_vec()))
794    }
795
796    fn lookup_entry(&self, key: &[u8]) -> Option<Self::EntryType> {
797        let key_start = key.as_ptr();
798        let key_len = key.len() as u32; // Wasm usize == 32bit.
799        let entry_id = unsafe { prims::state_lookup_entry(key_start, key_len) };
800        if entry_id == u64::MAX {
801            None
802        } else {
803            Some(StateEntry::open(entry_id, key.to_vec()))
804        }
805    }
806
807    fn delete_entry(&mut self, entry: Self::EntryType) -> Result<(), StateError> {
808        let key = entry.get_key();
809        let res = unsafe { prims::state_delete_entry(key.as_ptr(), key.len() as u32) };
810        match res {
811            0 => Err(StateError::SubtreeLocked),
812            1 => Err(StateError::EntryNotFound),
813            2 => Ok(()),
814            _ => crate::trap(), // cannot happen
815        }
816    }
817
818    fn delete_prefix(&mut self, prefix: &[u8]) -> Result<bool, StateError> {
819        let res = unsafe { prims::state_delete_prefix(prefix.as_ptr(), prefix.len() as u32) };
820        match res {
821            0 => Err(StateError::SubtreeLocked),
822            1 => Ok(false),
823            2 => Ok(true),
824            _ => crate::trap(), // cannot happen
825        }
826    }
827
828    fn iterator(&self, prefix: &[u8]) -> Result<Self::IterType, StateError> {
829        let prefix_start = prefix.as_ptr();
830        let prefix_len = prefix.len() as u32; // Wasm usize == 32bit.
831        let iterator_id = unsafe { prims::state_iterate_prefix(prefix_start, prefix_len) };
832        match iterator_id {
833            OK_NONE => Err(StateError::SubtreeWithPrefixNotFound),
834            ERR => Err(StateError::IteratorLimitForPrefixExceeded),
835            iterator_id => Ok(ExternStateIter {
836                iterator_id,
837            }),
838        }
839    }
840
841    fn delete_iterator(&mut self, iter: Self::IterType) {
842        // This call can never fail because the only way to get an `ExternStateIter`
843        // is through `StateApi::iterator(..)`. And this call consumes
844        // the iterator.
845        // These conditions rule out the two types of errors that the prims
846        // call can return, iterator not found and iterator already deleted.
847        // The iterator can also be deleted with `delete_iterator_by_id`, but that is
848        // only called when a [StateMapIter] or [StateSetIter] is dropped (which
849        // also drops the [ExternStateIter]). Again ruling out the already
850        // deleted error.
851        unsafe { prims::state_iterator_delete(iter.iterator_id) };
852    }
853}
854
855/// Encoding of Ok(None) that is returned by some host functions.
856const OK_NONE: u64 = u64::MAX;
857/// Encoding of Err that is returned by some host functions.
858const ERR: u64 = u64::MAX & !(1u64 << 62);
859
860impl Iterator for ExternStateIter {
861    type Item = StateEntry;
862
863    fn next(&mut self) -> Option<Self::Item> {
864        let res = unsafe { prims::state_iterator_next(self.iterator_id) };
865        match res {
866            OK_NONE => None,
867            // This next case means that an iterator never existed or was deleted.
868            // In both cases, it is not possible to call `next` on such an iterator with the current
869            // API. The only way to get an iterator is through
870            // [HasStateApi::iterator] and the only way to delete it is through
871            // [HasStateApi::delete_iterator].
872            ERR => None,
873            _ => {
874                // This will always return a valid size, because the iterator is guaranteed to
875                // exist.
876                let key_size = unsafe { prims::state_iterator_key_size(self.iterator_id) };
877                let mut key = Vec::with_capacity(key_size as usize);
878                // The key will always be read, because the iterator is guaranteed to exist.
879                unsafe {
880                    let num_read = prims::state_iterator_key_read(
881                        self.iterator_id,
882                        key.as_mut_ptr(),
883                        key_size,
884                        0,
885                    );
886                    key.set_len(num_read as usize);
887                };
888                Some(StateEntry::open(res, key))
889            }
890        }
891    }
892}
893
894impl<K, V, S> StateMap<K, V, S>
895where
896    S: HasStateApi,
897    K: Serialize,
898    V: Serial + DeserialWithState<S>,
899{
900    /// Lookup the value with the given key. Return [None] if there is no value
901    /// with the given key.
902    pub fn get(&self, key: &K) -> Option<StateRef<V>> {
903        let k = self.key_with_map_prefix(key);
904        self.state_api.lookup_entry(&k).map(|mut entry| {
905            // Unwrapping is safe when using only the high-level API.
906            StateRef::new(V::deserial_with_state(&self.state_api, &mut entry).unwrap_abort())
907        })
908    }
909
910    /// Lookup a mutable reference to the value with the given key. Return
911    /// [None] if there is no value with the given key.
912
913    pub fn get_mut(&mut self, key: &K) -> Option<StateRefMut<V, S>> {
914        let k = self.key_with_map_prefix(key);
915        let entry = self.state_api.lookup_entry(&k)?;
916        Some(StateRefMut::new(entry, self.state_api.clone()))
917    }
918
919    /// Inserts the value with the given key. If a value already exists at the
920    /// given key it is replaced and the old value is returned.
921    /// This only borrows the key, needed internally to avoid the need to clone
922    /// it first.
923    pub(crate) fn insert_borrowed(&mut self, key: &K, value: V) -> Option<V> {
924        let key_bytes = self.key_with_map_prefix(key);
925        // Unwrapping is safe because iter() holds a reference to the stateset.
926        match self.state_api.entry(key_bytes) {
927            EntryRaw::Vacant(vac) => {
928                let _ = vac.insert(&value).unwrap_abort();
929                None
930            }
931            EntryRaw::Occupied(mut occ) => {
932                // Unwrapping is safe when using only the high-level API.
933                let old_value =
934                    V::deserial_with_state(&self.state_api, occ.get_mut()).unwrap_abort();
935                occ.insert(&value);
936                Some(old_value)
937            }
938        }
939    }
940
941    /// Inserts the value with the given key. If a value already exists at the
942    /// given key it is replaced and the old value is returned.
943    ///
944    /// *Caution*: If `Option<V>` is to be deleted and contains a data structure
945    /// prefixed with `State` (such as [StateBox](crate::StateBox) or
946    /// [StateMap](crate::StateMap)), then it is important to call
947    /// [`Deletable::delete`](crate::Deletable::delete) on the value returned
948    /// when you're finished with it. Otherwise, it will remain in the
949    /// contract state.
950    #[must_use]
951    pub fn insert(&mut self, key: K, value: V) -> Option<V> { self.insert_borrowed(&key, value) }
952
953    /// Get an entry for the given key.
954    pub fn entry(&mut self, key: K) -> Entry<'_, K, V, S> {
955        let key_bytes = self.key_with_map_prefix(&key);
956        // Unwrapping is safe because iter() holds a reference to the stateset.
957        match self.state_api.lookup_entry(&key_bytes) {
958            None => Entry::Vacant(VacantEntry::new(key, key_bytes, self.state_api.clone())),
959            Some(mut state_entry) => {
960                // Unwrapping is safe when using only the high-level API.
961                let value =
962                    V::deserial_with_state(&self.state_api, &mut state_entry).unwrap_abort();
963                Entry::Occupied(OccupiedEntry::new(key, value, state_entry))
964            }
965        }
966    }
967
968    /// Return `true` if the map contains no elements.
969    pub fn is_empty(&self) -> bool { self.state_api.lookup_entry(&self.prefix).is_none() }
970
971    /// Clears the map, removing all key-value pairs.
972    /// This also includes values pointed at, if `V`, for example, is a
973    /// [StateBox]. **If applicable use [`clear_flat`](Self::clear_flat)
974    /// instead.**
975    pub fn clear(&mut self)
976    where
977        V: Deletable, {
978        // Delete all values pointed at by the statemap. This is necessary if `V` is a
979        // StateBox/StateMap.
980        for (_, value) in self.iter() {
981            value.value.delete()
982        }
983
984        // Then delete the map itself.
985        // Unwrapping is safe when only using the high-level API.
986        self.state_api.delete_prefix(&self.prefix).unwrap_abort();
987    }
988
989    /// Clears the map, removing all key-value pairs.
990    /// **This should be used over [`clear`](Self::clear) if it is
991    /// applicable.** It avoids recursive deletion of values since the
992    /// values are required to be _flat_.
993    ///
994    /// Unfortunately it is not possible to automatically choose between these
995    /// implementations. Once Rust gets trait specialization then this might
996    /// be possible.
997    pub fn clear_flat(&mut self)
998    where
999        V: Deserial, {
1000        // Delete only the map itself since the values have no pointers to state.
1001        // Thus there will be no dangling references.
1002        // Unwrapping is safe when only using the high-level API.
1003        self.state_api.delete_prefix(&self.prefix).unwrap_abort();
1004    }
1005
1006    /// Remove a key from the map, returning the value at the key if the key was
1007    /// previously in the map.
1008    ///
1009    /// *Caution*: If `V` is a [StateBox], [StateMap], then it is
1010    /// important to call [`Deletable::delete`] on the value returned when
1011    /// you're finished with it. Otherwise, it will remain in the contract
1012    /// state.
1013    #[must_use]
1014    pub fn remove_and_get(&mut self, key: &K) -> Option<V> {
1015        let key_bytes = self.key_with_map_prefix(key);
1016        // Unwrapping is safe because iter() holds a reference to the stateset.
1017        let entry_raw = self.state_api.entry(key_bytes);
1018        match entry_raw {
1019            EntryRaw::Vacant(_) => None,
1020            EntryRaw::Occupied(mut occ) => {
1021                // Unwrapping safe in high-level API.
1022                let old_value =
1023                    V::deserial_with_state(&self.state_api, occ.get_mut()).unwrap_abort();
1024                let _existed = self.state_api.delete_entry(occ.state_entry);
1025                Some(old_value)
1026            }
1027        }
1028    }
1029
1030    /// Remove a key from the map.
1031    /// This also deletes the value in the state.
1032    pub fn remove(&mut self, key: &K)
1033    where
1034        V: Deletable, {
1035        if let Some(v) = self.remove_and_get(key) {
1036            v.delete()
1037        }
1038    }
1039
1040    /// Serializes the key and prepends the unique map prefix to it.
1041    fn key_with_map_prefix(&self, key: &K) -> Vec<u8> {
1042        let mut key_with_prefix = self.prefix.to_vec();
1043        key.serial(&mut key_with_prefix).unwrap_abort();
1044        key_with_prefix
1045    }
1046}
1047
1048impl<'a, K, V, S: HasStateApi> Drop for StateMapIter<'a, K, V, S> {
1049    fn drop(&mut self) {
1050        // Delete the iterator to unlock the subtree.
1051        if let Some(valid) = self.state_iter.take() {
1052            self.state_api.delete_iterator(valid);
1053        }
1054    }
1055}
1056
1057impl<K, V, S> StateMap<K, V, S>
1058where
1059    S: HasStateApi,
1060{
1061    pub(crate) fn open(state_api: S, prefix: [u8; 8]) -> Self {
1062        Self {
1063            _marker_key: PhantomData,
1064            _marker_value: PhantomData,
1065            prefix,
1066            state_api,
1067        }
1068    }
1069
1070    /// Get an iterator over the key-value pairs of the map. The iterator
1071    /// returns values in increasing order of keys, where keys are ordered
1072    /// lexicographically via their serializations.
1073    pub fn iter(&self) -> StateMapIter<'_, K, V, S> {
1074        match self.state_api.iterator(&self.prefix) {
1075            Ok(state_iter) => StateMapIter {
1076                state_iter:       Some(state_iter),
1077                state_api:        self.state_api.clone(),
1078                _lifetime_marker: PhantomData,
1079            },
1080            Err(StateError::SubtreeWithPrefixNotFound) => StateMapIter {
1081                state_iter:       None,
1082                state_api:        self.state_api.clone(),
1083                _lifetime_marker: PhantomData,
1084            },
1085            _ => crate::trap(),
1086        }
1087    }
1088
1089    /// Like [iter](Self::iter), but allows modifying the values during
1090    /// iteration.
1091    pub fn iter_mut(&mut self) -> StateMapIterMut<'_, K, V, S> {
1092        match self.state_api.iterator(&self.prefix) {
1093            Ok(state_iter) => StateMapIterMut {
1094                state_iter:       Some(state_iter),
1095                state_api:        self.state_api.clone(),
1096                _lifetime_marker: PhantomData,
1097            },
1098            Err(StateError::SubtreeWithPrefixNotFound) => StateMapIterMut {
1099                state_iter:       None,
1100                state_api:        self.state_api.clone(),
1101                _lifetime_marker: PhantomData,
1102            },
1103            _ => crate::trap(),
1104        }
1105    }
1106}
1107
1108impl<'a, K, V, S: HasStateApi> Iterator for StateMapIter<'a, K, V, S>
1109where
1110    K: Deserial + 'a,
1111    V: DeserialWithState<S> + 'a,
1112{
1113    type Item = (StateRef<'a, K>, StateRef<'a, V>);
1114
1115    fn next(&mut self) -> Option<Self::Item> {
1116        let mut entry = self.state_iter.as_mut()?.next()?;
1117        let key = entry.get_key();
1118        let mut key_cursor = Cursor {
1119            data:   key,
1120            offset: 8, // Items in a map always start with the set prefix which is 8 bytes.
1121        };
1122        // Unwrapping is safe when only using the high-level API.
1123        let k = K::deserial(&mut key_cursor).unwrap_abort();
1124        let v = V::deserial_with_state(&self.state_api, &mut entry).unwrap_abort();
1125        Some((StateRef::new(k), StateRef::new(v)))
1126    }
1127}
1128
1129impl<'a, K, V: Serial, S: HasStateApi> Iterator for StateMapIterMut<'a, K, V, S>
1130where
1131    K: Deserial + 'a,
1132    V: DeserialWithState<S> + 'a,
1133    S::EntryType: 'a,
1134{
1135    type Item = (StateRef<'a, K>, StateRefMut<'a, V, S>);
1136
1137    fn next(&mut self) -> Option<Self::Item> {
1138        let entry = self.state_iter.as_mut()?.next()?;
1139
1140        let key_bytes = entry.get_key();
1141        let mut key_cursor = Cursor {
1142            data:   key_bytes,
1143            offset: 8, // Items in a map always start with the set prefix which is 8 bytes.
1144        };
1145        // Unwrapping is safe when only using the high-level API.
1146        let k = K::deserial(&mut key_cursor).unwrap_abort();
1147        // we do not load the value here, only on demand. This allows iteration over
1148        // keys to be reasonably efficient.
1149        Some((StateRef::new(k), StateRefMut::new(entry, self.state_api.clone())))
1150    }
1151}
1152
1153impl<'a, S: HasStateApi, V: Serial + DeserialWithState<S>> crate::ops::Deref
1154    for StateRefMut<'a, V, S>
1155{
1156    type Target = V;
1157
1158    #[inline(always)]
1159    fn deref(&self) -> &Self::Target { self.get() }
1160}
1161
1162impl<'a, S: HasStateApi, V: Serial + DeserialWithState<S>> crate::ops::DerefMut
1163    for StateRefMut<'a, V, S>
1164{
1165    #[inline(always)]
1166    fn deref_mut(&mut self) -> &mut Self::Target { self.get_mut() }
1167}
1168
1169/// When dropped, the value, `V`, is written to the entry in the contract state.
1170impl<'a, V: Serial, S: HasStateApi> Drop for StateRefMut<'a, V, S> {
1171    fn drop(&mut self) { self.store_mutations() }
1172}
1173
1174impl<'a, V, S> StateRefMut<'a, V, S>
1175where
1176    V: Serial,
1177    S: HasStateApi,
1178{
1179    /// Get a shared reference to the value. Note that [StateRefMut](Self) also
1180    /// implements [Deref](crate::ops::Deref) so this conversion can happen
1181    /// implicitly.
1182    pub fn get(&self) -> &V
1183    where
1184        V: DeserialWithState<S>, {
1185        let lv = unsafe { &mut *self.lazy_value.get() };
1186        if let Some(v) = lv {
1187            v
1188        } else {
1189            lv.insert(self.load_value())
1190        }
1191    }
1192
1193    /// Get a unique reference to the value. Note that [StateRefMut](Self) also
1194    /// implements [DerefMut](crate::ops::DerefMut) so this conversion can
1195    /// happen implicitly.
1196    pub fn get_mut(&mut self) -> &mut V
1197    where
1198        V: DeserialWithState<S>, {
1199        let lv = unsafe { &mut *self.lazy_value.get() };
1200        if let Some(v) = lv {
1201            v
1202        } else {
1203            lv.insert(self.load_value())
1204        }
1205    }
1206
1207    /// Load the value referenced by the entry from the chain data.
1208    fn load_value(&self) -> V
1209    where
1210        V: DeserialWithState<S>, {
1211        // Safe to unwrap below, since the entry can only be `None`, using methods which
1212        // are consuming self.
1213        let entry = unsafe { &mut *self.entry.get() };
1214        entry.move_to_start();
1215        V::deserial_with_state(&self.state_api, entry).unwrap_abort()
1216    }
1217
1218    /// Set the value. Overwrites the existing one.
1219    pub fn set(&mut self, new_val: V) {
1220        // Safe to unwrap below, since the entry can only be `None`, using methods which
1221        // are consuming self.
1222        let entry = self.entry.get_mut();
1223        entry.move_to_start();
1224        new_val.serial(entry).unwrap_abort();
1225        let _ = self.lazy_value.get_mut().insert(new_val);
1226    }
1227
1228    /// Update the existing value with the given function.
1229    pub fn update<F>(&mut self, f: F)
1230    where
1231        V: DeserialWithState<S>,
1232        F: FnOnce(&mut V), {
1233        let lv = self.lazy_value.get_mut();
1234        // Safe to unwrap below, since the entry can only be `None`, using methods which
1235        // are consuming self.
1236        let entry = self.entry.get_mut();
1237        let value = if let Some(v) = lv {
1238            v
1239        } else {
1240            entry.move_to_start();
1241            let value = V::deserial_with_state(&self.state_api, entry).unwrap_abort();
1242            lv.insert(value)
1243        };
1244
1245        // Mutate the value (perhaps only in memory, depends on the type).
1246        f(value);
1247        entry.move_to_start();
1248        value.serial(entry).unwrap_abort()
1249    }
1250
1251    /// Write to the state entry if the value is loaded.
1252    pub(crate) fn store_mutations(&mut self) {
1253        if let Some(value) = self.lazy_value.get_mut() {
1254            // Safe to unwrap below, since the entry can only be `None`, using methods which
1255            // are consuming self.
1256            let entry = self.entry.get_mut();
1257            entry.move_to_start();
1258            value.serial(entry).unwrap_abort();
1259        }
1260    }
1261
1262    /// Drop the ref without storing mutations to the state entry.
1263    pub(crate) fn drop_without_storing(mut self) { *self.lazy_value.get_mut() = None; }
1264}
1265
1266impl<K, V, S> Serial for StateMap<K, V, S> {
1267    fn serial<W: Write>(&self, out: &mut W) -> Result<(), W::Err> { out.write_all(&self.prefix) }
1268}
1269
1270impl<T, S> StateSet<T, S>
1271where
1272    T: Serialize,
1273    S: HasStateApi,
1274{
1275    /// Adds a value to the set.
1276    /// If the set did not have this value, `true` is returned. Otherwise,
1277    /// `false`.
1278    pub fn insert(&mut self, value: T) -> bool {
1279        let key_bytes = self.key_with_set_prefix(&value);
1280        match self.state_api.entry(key_bytes) {
1281            EntryRaw::Vacant(vac) => {
1282                let _ = vac.insert_raw(&[]);
1283                true
1284            }
1285            EntryRaw::Occupied(_) => false,
1286        }
1287    }
1288
1289    /// Returns `true` if the set contains no elements.
1290    pub fn is_empty(&self) -> bool { self.state_api.lookup_entry(&self.prefix).is_none() }
1291
1292    /// Returns `true` if the set contains a value.
1293    pub fn contains(&self, value: &T) -> bool {
1294        let key_bytes = self.key_with_set_prefix(value);
1295        self.state_api.lookup_entry(&key_bytes).is_some()
1296    }
1297
1298    /// Clears the set, removing all values.
1299    /// This also includes values pointed at, if `V`, for example, is a
1300    /// [StateBox].
1301    // Note: This does not use delete() because delete consumes self.
1302    pub fn clear(&mut self) {
1303        // Delete all values in the stateset. Since `T` is serializable
1304        // there is no need to recursively delete the values since
1305        // serializable values cannot have pointers to other parts of state.
1306        // Unwrapping is safe when only using the high-level API.
1307        self.state_api.delete_prefix(&self.prefix).unwrap_abort();
1308    }
1309
1310    /// Removes a value from the set. Returns whether the value was present in
1311    /// the set.
1312    pub fn remove(&mut self, value: &T) -> bool {
1313        let key_bytes = self.key_with_set_prefix(value);
1314
1315        // Unwrapping is safe, because iter() keeps a reference to the stateset.
1316        match self.state_api.entry(key_bytes) {
1317            EntryRaw::Vacant(_) => false,
1318            EntryRaw::Occupied(occ) => {
1319                // Unwrapping is safe, because iter() keeps a reference to the stateset.
1320                self.state_api.delete_entry(occ.get()).unwrap_abort();
1321                true
1322            }
1323        }
1324    }
1325
1326    fn key_with_set_prefix(&self, key: &T) -> Vec<u8> {
1327        let mut key_with_prefix = self.prefix.to_vec();
1328        key.serial(&mut key_with_prefix).unwrap_abort();
1329        key_with_prefix
1330    }
1331}
1332
1333impl<T, S: HasStateApi> StateSet<T, S> {
1334    pub(crate) fn open(state_api: S, prefix: [u8; 8]) -> Self {
1335        Self {
1336            _marker: PhantomData,
1337            prefix,
1338            state_api,
1339        }
1340    }
1341
1342    /// Get an iterator over the elements in the `StateSet`. The iterator
1343    /// returns elements in increasing order, where elements are ordered
1344    /// lexicographically via their serializations.
1345    pub fn iter(&self) -> StateSetIter<T, S> {
1346        match self.state_api.iterator(&self.prefix) {
1347            Ok(state_iter) => StateSetIter {
1348                state_iter:       Some(state_iter),
1349                state_api:        self.state_api.clone(),
1350                _marker_lifetime: PhantomData,
1351            },
1352            Err(StateError::SubtreeWithPrefixNotFound) => StateSetIter {
1353                state_iter:       None,
1354                state_api:        self.state_api.clone(),
1355                _marker_lifetime: PhantomData,
1356            },
1357            _ => crate::trap(),
1358        }
1359    }
1360}
1361
1362impl<T: Serial, S: HasStateApi> StateBox<T, S> {
1363    /// Create a new statebox.
1364    pub(crate) fn new(value: T, state_api: S, entry: S::EntryType) -> Self {
1365        StateBox {
1366            state_api,
1367            inner: UnsafeCell::new(StateBoxInner::Loaded {
1368                entry,
1369                modified: true,
1370                value,
1371            }),
1372        }
1373    }
1374
1375    /// Return the key under which the value is stored in the contract state
1376    /// trie.
1377    pub(crate) fn get_location(&self) -> &[u8] {
1378        match unsafe { &*self.inner.get() } {
1379            StateBoxInner::Loaded {
1380                entry,
1381                ..
1382            } => entry.get_key(),
1383            StateBoxInner::Reference {
1384                prefix,
1385            } => &prefix[..],
1386        }
1387    }
1388}
1389
1390impl<S: HasStateApi, T: Serial + DeserialWithState<S>> crate::ops::Deref for StateBox<T, S> {
1391    type Target = T;
1392
1393    #[inline(always)]
1394    fn deref(&self) -> &Self::Target { self.get() }
1395}
1396
1397impl<S: HasStateApi, T: Serial + DeserialWithState<S>> crate::ops::DerefMut for StateBox<T, S> {
1398    #[inline(always)]
1399    fn deref_mut(&mut self) -> &mut Self::Target { self.get_mut() }
1400}
1401
1402impl<T: Serial, S: HasStateApi> Drop for StateBox<T, S> {
1403    fn drop(&mut self) {
1404        if let StateBoxInner::Loaded {
1405            entry,
1406            modified,
1407            value,
1408        } = self.inner.get_mut()
1409        {
1410            if *modified {
1411                entry.move_to_start();
1412                value.serial(entry).unwrap_abort();
1413            }
1414        }
1415    }
1416}
1417
1418/// Return a reference to the value stored inside the [`StateBoxInner`], as well
1419/// as a reference to the flag that indicates whether the value has been
1420/// modified or not.
1421fn get_with_inner<'a, T: Serial + DeserialWithState<S>, S: HasStateApi>(
1422    state_api: &S,
1423    inner: &'a mut StateBoxInner<T, S>,
1424) -> (&'a mut T, &'a mut bool) {
1425    let (entry, value) = match inner {
1426        StateBoxInner::Loaded {
1427            value,
1428            modified,
1429            ..
1430        } => return (value, modified),
1431        StateBoxInner::Reference {
1432            prefix,
1433        } => {
1434            let mut entry = state_api.lookup_entry(prefix).unwrap_abort();
1435            // new entry, positioned at the start.
1436            let value = T::deserial_with_state(state_api, &mut entry).unwrap_abort();
1437            (entry, value)
1438        }
1439    };
1440    *inner = StateBoxInner::Loaded {
1441        entry,
1442        modified: false,
1443        value,
1444    };
1445    match inner {
1446        StateBoxInner::Loaded {
1447            value,
1448            modified,
1449            ..
1450        } => (value, modified),
1451        StateBoxInner::Reference {
1452            ..
1453        } => {
1454            // We just set it to loaded.
1455            unsafe { crate::hint::unreachable_unchecked() }
1456        }
1457    }
1458}
1459
1460impl<T, S> StateBox<T, S>
1461where
1462    T: Serial + DeserialWithState<S>,
1463    S: HasStateApi,
1464{
1465    /// Get a reference to the value.
1466    pub fn get(&self) -> &T {
1467        let inner = unsafe { &mut *self.inner.get() };
1468        get_with_inner(&self.state_api, inner).0
1469    }
1470
1471    /// Get a mutable reference to the value. If the value is modified in-memory
1472    /// then it will be stored when the box is dropped.
1473    pub fn get_mut(&mut self) -> &mut T {
1474        let inner = self.inner.get_mut();
1475        let (value, modified) = get_with_inner(&self.state_api, inner);
1476        *modified = true;
1477        value
1478    }
1479
1480    /// Replace the value with the provided one. The current value is returned.
1481    /// Note that if the type `T` contains references to state, e.g., is a
1482    /// [`StateBox`], then it must be [deleted](Deletable::delete) to avoid
1483    /// space leaks.
1484    #[must_use]
1485    pub fn replace(&mut self, new_val: T) -> T {
1486        let (entry, value) = self.ensure_cached();
1487        entry.move_to_start();
1488        new_val.serial(entry).unwrap_abort();
1489        mem::replace(value, new_val)
1490    }
1491
1492    /// Update the existing value with the given function.
1493    /// The supplied function may return some data, which is then returned by
1494    /// [`update`](Self::update).
1495    pub fn update<F, A>(&mut self, f: F) -> A
1496    where
1497        F: FnOnce(&mut T) -> A, {
1498        let (entry, value) = self.ensure_cached();
1499        // Mutate the value (perhaps only in memory, depends on the type).
1500        let res = f(value);
1501        entry.move_to_start();
1502        value.serial(entry).unwrap_abort();
1503        res
1504    }
1505
1506    /// If the value isn't cached, load the value from the state. Return a
1507    /// reference to the entry, and the value. Note that **if the value is
1508    /// modified, the entry should be used to write it.**
1509    fn ensure_cached(&mut self) -> (&mut S::EntryType, &mut T) {
1510        let inner = self.inner.get_mut();
1511        let (entry, modified, value) = match inner {
1512            StateBoxInner::Loaded {
1513                entry,
1514                value,
1515                ..
1516            } => return (entry, value),
1517            StateBoxInner::Reference {
1518                prefix,
1519            } => {
1520                let mut entry = self.state_api.lookup_entry(prefix).unwrap_abort();
1521                // new entry, positioned at the start.
1522                let value = T::deserial_with_state(&self.state_api, &mut entry).unwrap_abort();
1523                (entry, false, value)
1524            }
1525        };
1526        *inner = StateBoxInner::Loaded {
1527            entry,
1528            modified,
1529            value,
1530        };
1531        match inner {
1532            StateBoxInner::Loaded {
1533                entry,
1534                value,
1535                ..
1536            } => (entry, value),
1537            StateBoxInner::Reference {
1538                ..
1539            } => {
1540                // We just set it to loaded
1541                unsafe { crate::hint::unreachable_unchecked() }
1542            }
1543        }
1544    }
1545}
1546
1547impl<T: Serial, S: HasStateApi> Serial for StateBox<T, S> {
1548    fn serial<W: Write>(&self, out: &mut W) -> Result<(), W::Err> {
1549        out.write_all(self.get_location())
1550    }
1551}
1552
1553impl<T, S> Serial for StateSet<T, S> {
1554    fn serial<W: Write>(&self, out: &mut W) -> Result<(), W::Err> { out.write_all(&self.prefix) }
1555}
1556
1557/// Unlock the part of the tree locked by the iterator.
1558impl<'a, T, S: HasStateApi> Drop for StateSetIter<'a, T, S> {
1559    #[inline]
1560    fn drop(&mut self) {
1561        // Delete the iterator to unlock the subtree.
1562        if let Some(valid) = self.state_iter.take() {
1563            self.state_api.delete_iterator(valid);
1564        }
1565    }
1566}
1567
1568impl<'a, T, S: HasStateApi> Iterator for StateSetIter<'a, T, S>
1569where
1570    T: DeserialWithState<S>,
1571{
1572    type Item = StateRef<'a, T>;
1573
1574    #[inline(always)]
1575    fn next(&mut self) -> Option<Self::Item> {
1576        let entry = self.state_iter.as_mut()?.next()?;
1577        let key = entry.get_key();
1578        let mut key_cursor = Cursor {
1579            data:   key,
1580            offset: 8, // Items in a set always start with the set prefix which is 8 bytes.
1581        };
1582        // Unwrapping is safe when only using the high-level API.
1583        let t = T::deserial_with_state(&self.state_api, &mut key_cursor).unwrap_abort();
1584        Some(StateRef::new(t))
1585    }
1586}
1587
1588// # Trait implementations for Parameter
1589
1590impl Default for ExternParameter {
1591    #[inline(always)]
1592    fn default() -> Self {
1593        ExternParameter {
1594            cursor: Cursor::new(ExternParameterDataPlaceholder {}),
1595        }
1596    }
1597}
1598
1599impl Read for ExternParameter {
1600    fn read(&mut self, buf: &mut [u8]) -> ParseResult<usize> {
1601        let len: u32 = {
1602            match buf.len().try_into() {
1603                Ok(v) => v,
1604                _ => return Err(ParseError::default()),
1605            }
1606        };
1607        let num_read = unsafe {
1608            // parameter 0 always exists, so this is safe.
1609            prims::get_parameter_section(0, buf.as_mut_ptr(), len, self.cursor.offset as u32)
1610        };
1611
1612        self.cursor.offset += num_read as usize;
1613        Ok(num_read as usize)
1614    }
1615}
1616
1617impl HasSize for ExternParameterDataPlaceholder {
1618    #[inline(always)]
1619    // parameter 0 always exists so this is correct
1620    fn size(&self) -> u32 { unsafe { prims::get_parameter_size(0) as u32 } }
1621}
1622
1623impl HasSize for ExternParameter {
1624    #[inline(always)]
1625    fn size(&self) -> u32 { self.cursor.data.size() }
1626}
1627
1628impl Seek for ExternParameter {
1629    type Err = ();
1630
1631    #[inline(always)]
1632    fn seek(&mut self, pos: SeekFrom) -> Result<u32, Self::Err> { self.cursor.seek(pos) }
1633
1634    #[inline(always)]
1635    fn cursor_position(&self) -> u32 { self.cursor.cursor_position() }
1636}
1637
1638impl HasParameter for ExternParameter {}
1639
1640/// The read implementation uses host functions to read chunks of return value
1641/// on demand.
1642impl Read for ExternCallResponse {
1643    fn read(&mut self, buf: &mut [u8]) -> ParseResult<usize> {
1644        let len: u32 = {
1645            match buf.len().try_into() {
1646                Ok(v) => v,
1647                _ => return Err(ParseError::default()),
1648            }
1649        };
1650        let num_read = unsafe {
1651            prims::get_parameter_section(
1652                self.i.into(),
1653                buf.as_mut_ptr(),
1654                len,
1655                self.current_position,
1656            )
1657        };
1658        if num_read >= 0 {
1659            self.current_position += num_read as u32;
1660            Ok(num_read as usize)
1661        } else {
1662            Err(ParseError::default())
1663        }
1664    }
1665}
1666
1667impl HasCallResponse for ExternCallResponse {
1668    // CallResponse can only be constured in this crate. As a result whenever it is
1669    // constructed it will point to a valid parameter, which means that
1670    // `get_parameter_size` will always return a non-negative value.
1671    fn size(&self) -> u32 { unsafe { prims::get_parameter_size(self.i.get()) as u32 } }
1672}
1673
1674/// # Trait implementations for the chain metadata.
1675impl HasChainMetadata for ExternChainMeta {
1676    #[inline(always)]
1677    fn slot_time(&self) -> SlotTime {
1678        Timestamp::from_timestamp_millis(unsafe { prims::get_slot_time() })
1679    }
1680}
1681
1682impl AttributesCursor {
1683    fn next_item(&mut self, buf: &mut [u8]) -> Option<(AttributeTag, u8)> {
1684        if self.remaining_items == 0 {
1685            return None;
1686        }
1687
1688        let (tag_value_len, num_read) = unsafe {
1689            let mut tag_value_len = MaybeUninit::<[u8; 2]>::uninit();
1690            // Should succeed, otherwise host violated precondition.
1691            let num_read = prims::get_policy_section(
1692                tag_value_len.as_mut_ptr() as *mut u8,
1693                2,
1694                self.current_position,
1695            );
1696            (tag_value_len.assume_init(), num_read)
1697        };
1698        self.current_position += num_read;
1699        if tag_value_len[1] > 31 {
1700            // Should not happen because all attributes fit into 31 bytes.
1701            return None;
1702        }
1703        let num_read = unsafe {
1704            prims::get_policy_section(
1705                buf.as_mut_ptr(),
1706                u32::from(tag_value_len[1]),
1707                self.current_position,
1708            )
1709        };
1710        self.current_position += num_read;
1711        self.remaining_items -= 1;
1712        Some((AttributeTag(tag_value_len[0]), tag_value_len[1]))
1713    }
1714}
1715
1716impl HasPolicy for Policy<AttributesCursor> {
1717    type Iterator = PolicyAttributesIter;
1718
1719    fn identity_provider(&self) -> IdentityProvider { self.identity_provider }
1720
1721    fn created_at(&self) -> Timestamp { self.created_at }
1722
1723    fn valid_to(&self) -> Timestamp { self.valid_to }
1724
1725    #[inline(always)]
1726    fn next_item(&mut self, buf: &mut [u8; 31]) -> Option<(AttributeTag, u8)> {
1727        self.items.next_item(buf)
1728    }
1729
1730    fn attributes(&self) -> Self::Iterator {
1731        PolicyAttributesIter {
1732            cursor: AttributesCursor {
1733                current_position: 0,
1734                remaining_items:  self.items.total_items,
1735                total_items:      self.items.total_items,
1736            },
1737        }
1738    }
1739}
1740
1741impl Iterator for PolicyAttributesIter {
1742    type Item = (AttributeTag, AttributeValue);
1743
1744    fn next(&mut self) -> Option<Self::Item> {
1745        let mut inner = [0u8; 32];
1746        let (tag, len) = self.cursor.next_item(&mut inner[1..])?;
1747        inner[0] = len;
1748        Some((tag, unsafe { AttributeValue::new_unchecked(inner) }))
1749    }
1750}
1751
1752impl ExactSizeIterator for PolicyAttributesIter {
1753    fn len(&self) -> usize { self.cursor.remaining_items as usize }
1754}
1755
1756/// An iterator over policies using host functions to supply the data.
1757/// The main interface to using this type is via the methods of the [Iterator](https://doc.rust-lang.org/std/iter/trait.Iterator.html)
1758/// and [ExactSizeIterator](https://doc.rust-lang.org/std/iter/trait.ExactSizeIterator.html) traits.
1759pub struct PoliciesIterator {
1760    /// Position in the policies binary serialization.
1761    pos:             u32,
1762    /// Number of remaining items in the stream.
1763    remaining_items: u16,
1764}
1765
1766impl Iterator for PoliciesIterator {
1767    type Item = Policy<AttributesCursor>;
1768
1769    fn next(&mut self) -> Option<Self::Item> {
1770        if self.remaining_items == 0 {
1771            return None;
1772        }
1773        // 2 for total size of this section, 4 for identity_provider,
1774        // 8 bytes for created_at, 8 for valid_to, and 2 for
1775        // the length
1776        let mut buf: MaybeUninit<[u8; 2 + 4 + 8 + 8 + 2]> = MaybeUninit::uninit();
1777        let buf = unsafe {
1778            prims::get_policy_section(buf.as_mut_ptr() as *mut u8, 2 + 4 + 8 + 8 + 2, self.pos);
1779            buf.assume_init()
1780        };
1781        let skip_part: [u8; 2] = buf[0..2].try_into().unwrap_abort();
1782        let ip_part: [u8; 4] = buf[2..2 + 4].try_into().unwrap_abort();
1783        let created_at_part: [u8; 8] = buf[2 + 4..2 + 4 + 8].try_into().unwrap_abort();
1784        let valid_to_part: [u8; 8] = buf[2 + 4 + 8..2 + 4 + 8 + 8].try_into().unwrap_abort();
1785        let len_part: [u8; 2] = buf[2 + 4 + 8 + 8..2 + 4 + 8 + 8 + 2].try_into().unwrap_abort();
1786        let identity_provider = IdentityProvider::from_le_bytes(ip_part);
1787        let created_at = Timestamp::from_timestamp_millis(u64::from_le_bytes(created_at_part));
1788        let valid_to = Timestamp::from_timestamp_millis(u64::from_le_bytes(valid_to_part));
1789        let remaining_items = u16::from_le_bytes(len_part);
1790        let attributes_start = self.pos + 2 + 4 + 8 + 8 + 2;
1791        self.pos += u32::from(u16::from_le_bytes(skip_part)) + 2;
1792        self.remaining_items -= 1;
1793        Some(Policy {
1794            identity_provider,
1795            created_at,
1796            valid_to,
1797            items: AttributesCursor {
1798                current_position: attributes_start,
1799                remaining_items,
1800                total_items: remaining_items,
1801            },
1802        })
1803    }
1804
1805    fn size_hint(&self) -> (usize, Option<usize>) {
1806        let rem = self.remaining_items as usize;
1807        (rem, Some(rem))
1808    }
1809}
1810
1811impl ExactSizeIterator for PoliciesIterator {
1812    #[inline(always)]
1813    fn len(&self) -> usize { self.remaining_items as usize }
1814}
1815
1816impl<T: sealed::ContextType> HasCommonData for ExternContext<T> {
1817    type MetadataType = ExternChainMeta;
1818    type ParamType = ExternParameter;
1819    type PolicyIteratorType = PoliciesIterator;
1820    type PolicyType = Policy<AttributesCursor>;
1821
1822    #[inline(always)]
1823    fn metadata(&self) -> &Self::MetadataType { &ExternChainMeta {} }
1824
1825    fn policies(&self) -> PoliciesIterator {
1826        let mut buf: MaybeUninit<[u8; 2]> = MaybeUninit::uninit();
1827        let buf = unsafe {
1828            prims::get_policy_section(buf.as_mut_ptr() as *mut u8, 2, 0);
1829            buf.assume_init()
1830        };
1831        PoliciesIterator {
1832            pos:             2, // 2 because we already read 2 bytes.
1833            remaining_items: u16::from_le_bytes(buf),
1834        }
1835    }
1836
1837    #[inline(always)]
1838    fn parameter_cursor(&self) -> Self::ParamType { ExternParameter::default() }
1839}
1840
1841/// Tag of the transfer operation expected by the host. See [prims::invoke].
1842const INVOKE_TRANSFER_TAG: u32 = 0;
1843/// Tag of the call operation expected by the host. See [prims::invoke].
1844const INVOKE_CALL_TAG: u32 = 1;
1845/// Tag of the query account balance operation expected by the host. See
1846/// [prims::invoke].
1847const INVOKE_QUERY_ACCOUNT_BALANCE_TAG: u32 = 2;
1848/// Tag of the query contract balance operation expected by the host. See
1849/// [prims::invoke].
1850const INVOKE_QUERY_CONTRACT_BALANCE_TAG: u32 = 3;
1851/// Tag of the query exchange rates operation expected by the host. See
1852/// [prims::invoke].
1853const INVOKE_QUERY_EXCHANGE_RATES_TAG: u32 = 4;
1854/// Tag of the operation to check the account's signature [prims::invoke].
1855const INVOKE_CHECK_ACCOUNT_SIGNATURE_TAG: u32 = 5;
1856/// Tag of the query account's public keys [prims::invoke].
1857const INVOKE_QUERY_ACCOUNT_PUBLIC_KEYS_TAG: u32 = 6;
1858/// Tag of the query contract module reference operation. See [prims::invoke].
1859#[cfg(feature = "p7")]
1860const INVOKE_QUERY_CONTRACT_MODULE_REFERENCE_TAG: u32 = 7;
1861/// Tag of the query contract name operation. See [prims::invoke].
1862#[cfg(feature = "p7")]
1863const INVOKE_QUERY_CONTRACT_NAME_TAG: u32 = 8;
1864
1865/// Check whether the response code from calling `invoke` is encoding a failure
1866/// and map out the byte used for the error code.
1867/// A successful response code has the last 5 bytes unset.
1868#[inline(always)]
1869fn get_invoke_failure_code(code: u64) -> Option<u8> {
1870    if code & 0xff_ffff_ffff == 0 {
1871        None
1872    } else {
1873        let error_code = (code & 0xff_0000_0000) >> 32;
1874        Some(error_code as u8)
1875    }
1876}
1877
1878/// Decode the the response code.
1879///
1880/// The response is encoded as follows.
1881/// - Success if the last 5 bytes are all zero:
1882///   - the first 3 bytes encodes the return value index, except the first bit,
1883///     which is used to indicate whether the contract state was modified.
1884/// - In case of failure the 4th byte is used, and encodes the environment
1885///   failure, where:
1886///   - 0x01 encodes amount too large.
1887///   - 0x02 encodes missing account.
1888fn parse_transfer_response_code(code: u64) -> TransferResult {
1889    if let Some(error_code) = get_invoke_failure_code(code) {
1890        match error_code {
1891            0x01 => Err(TransferError::AmountTooLarge),
1892            0x02 => Err(TransferError::MissingAccount),
1893            _ => crate::trap(), // host precondition violation
1894        }
1895    } else {
1896        Ok(())
1897    }
1898}
1899
1900/// Decode the response code from calling upgrade.
1901///
1902/// The response is encoded as follows.
1903/// - Success if the last 5 bytes are all zero:
1904///   - the first 3 bytes encodes the return value index, except the first bit,
1905///     which is used to indicate whether the contract state was modified.
1906/// - In case of failure the 4th byte is used, and encodes the environment
1907///   failure, where:
1908///   - 0x07 encodes missing module.
1909///   - 0x08 encodes missing contract.
1910///   - 0x09 encodes module being an unsupported version.
1911#[inline(always)]
1912fn parse_upgrade_response_code(code: u64) -> UpgradeResult {
1913    if let Some(error_code) = get_invoke_failure_code(code) {
1914        match error_code {
1915            0x07 => Err(UpgradeError::MissingModule),
1916            0x08 => Err(UpgradeError::MissingContract),
1917            0x09 => Err(UpgradeError::UnsupportedModuleVersion),
1918            _ => crate::trap(), // host precondition violation
1919        }
1920    } else {
1921        Ok(())
1922    }
1923}
1924
1925/// Decode the the response code.
1926///
1927/// The response is encoded as follows.
1928/// - Success if the last 5 bytes are all zero:
1929///   - the first 3 bytes encodes the return value index, except the first bit,
1930///     which is used to indicate whether the contract state was modified.
1931/// - In case of failure:
1932///   - if the 4th byte is 0 then the remaining 4 bytes encode the rejection
1933///     reason from the contract
1934///   - otherwise only the 4th byte is used, and encodes the environment
1935///     failure.
1936///     - 0x01 encodes amount too large.
1937///     - 0x02 encodes missing account.
1938///     - 0x03 encodes missing contract.
1939///     - 0x04 encodes missing entrypoint.
1940///     - 0x05 encodes message failed.
1941///     - 0x06 encodes trap.
1942fn parse_call_response_code(code: u64) -> CallContractResult<ExternCallResponse> {
1943    if let Some(error_code) = get_invoke_failure_code(code) {
1944        match error_code {
1945            0x00 =>
1946            // response with logic error and return value.
1947            {
1948                let reason = (0x0000_0000_ffff_ffff & code) as u32 as i32;
1949                if reason == 0 {
1950                    crate::trap()
1951                } else {
1952                    let rv = (code >> 40) as u32;
1953                    if rv > 0 {
1954                        Err(CallContractError::LogicReject {
1955                            reason,
1956                            return_value: ExternCallResponse::new(unsafe {
1957                                NonZeroU32::new_unchecked(rv)
1958                            }),
1959                        })
1960                    } else {
1961                        unsafe { crate::hint::unreachable_unchecked() } // host precondition violation.
1962                    }
1963                }
1964            }
1965            0x01 => Err(CallContractError::AmountTooLarge),
1966            0x02 => Err(CallContractError::MissingAccount),
1967            0x03 => Err(CallContractError::MissingContract),
1968            0x04 => Err(CallContractError::MissingEntrypoint),
1969            0x05 => Err(CallContractError::MessageFailed),
1970            0x06 => Err(CallContractError::Trap),
1971            _ => unsafe { crate::hint::unreachable_unchecked() }, // host precondition violation
1972        }
1973    } else {
1974        // Map out the 3 bytes encoding the return value index.
1975        let rv = (code >> 40) as u32;
1976
1977        let tag = 0x80_0000u32; // Mask for the first bit.
1978        if tag & rv != 0 {
1979            // Check the bit, indicating a contract state change.
1980            Ok((true, NonZeroU32::new(rv & !tag).map(ExternCallResponse::new)))
1981        } else {
1982            Ok((false, NonZeroU32::new(rv).map(ExternCallResponse::new)))
1983        }
1984    }
1985}
1986
1987/// Decode the account balance response code.
1988///
1989/// - Success if the last 5 bytes are all zero:
1990///   - the first 3 bytes encodes the return value index.
1991/// - In case of failure the 4th byte is used, and encodes the environment
1992///   failure where:
1993///    - '0x02' encodes missing account.
1994fn parse_query_account_balance_response_code(
1995    code: u64,
1996) -> Result<ExternCallResponse, QueryAccountBalanceError> {
1997    if let Some(error_code) = get_invoke_failure_code(code) {
1998        if error_code == 0x02 {
1999            Err(QueryAccountBalanceError)
2000        } else {
2001            unsafe { crate::hint::unreachable_unchecked() }
2002        }
2003    } else {
2004        // Map out the 3 bytes encoding the return value index.
2005        let return_value_index = NonZeroU32::new((code >> 40) as u32).unwrap_abort();
2006        Ok(ExternCallResponse::new(return_value_index))
2007    }
2008}
2009
2010/// Decode the contract balance response code.
2011///
2012/// - Success if the last 5 bytes are all zero:
2013///   - the first 3 bytes encodes the return value index.
2014/// - In case of failure the 4th byte is used, and encodes the environment
2015///   failure where:
2016///    - '0x03' encodes missing contract.
2017fn parse_query_contract_balance_response_code(
2018    code: u64,
2019) -> Result<ExternCallResponse, QueryContractBalanceError> {
2020    if let Some(error_code) = get_invoke_failure_code(code) {
2021        if error_code == 0x03 {
2022            Err(QueryContractBalanceError)
2023        } else {
2024            unsafe { crate::hint::unreachable_unchecked() }
2025        }
2026    } else {
2027        // Map out the 3 bytes encoding the return value index.
2028        let return_value_index = NonZeroU32::new((code >> 40) as u32).unwrap_abort();
2029        Ok(ExternCallResponse::new(return_value_index))
2030    }
2031}
2032
2033/// Decode the account public keys query response code.
2034///
2035/// - Success if the last 5 bytes are all zero:
2036///   - the first 3 bytes encodes the return value index.
2037/// - In case of failure the 4th byte is used, and encodes the environment
2038///   failure where:
2039///    - '0x02' encodes missing account.
2040fn parse_query_account_public_keys_response_code(
2041    code: u64,
2042) -> Result<ExternCallResponse, QueryAccountPublicKeysError> {
2043    if let Some(error_code) = get_invoke_failure_code(code) {
2044        if error_code == 0x02 {
2045            Err(QueryAccountPublicKeysError)
2046        } else {
2047            unsafe { crate::hint::unreachable_unchecked() }
2048        }
2049    } else {
2050        // Map out the 3 bytes encoding the return value index.
2051        let return_value_index = NonZeroU32::new((code >> 40) as u32).unwrap_abort();
2052        Ok(ExternCallResponse::new(return_value_index))
2053    }
2054}
2055
2056/// Decode the response from checking account signatures.
2057///
2058/// - Success if the last 5 bytes are all zero:
2059/// - In case of failure the 4th byte is used, and encodes the environment
2060///   failure where:
2061///    - '0x02' encodes missing account.
2062///    - '0x0a' encodes malformed data, i.e., the call was made with incorrect
2063///      data.
2064///    - '0x0b' encodes that signature validation failed.
2065fn parse_check_account_signature_response_code(
2066    code: u64,
2067) -> Result<bool, CheckAccountSignatureError> {
2068    if let Some(error_code) = get_invoke_failure_code(code) {
2069        if error_code == 0x02 {
2070            Err(CheckAccountSignatureError::MissingAccount)
2071        } else if error_code == 0x0a {
2072            Err(CheckAccountSignatureError::MalformedData)
2073        } else if error_code == 0x0b {
2074            Ok(false)
2075        } else {
2076            unsafe { crate::hint::unreachable_unchecked() }
2077        }
2078    } else {
2079        Ok(true)
2080    }
2081}
2082
2083/// Decode the exchange rate response code.
2084///
2085/// - Success if the last 5 bytes are all zero:
2086///   - the first 3 bytes encodes the return value index.
2087/// - In case of failure we throw a runtime error, since this query is not
2088///   expected to fail.
2089fn parse_query_exchange_rates_response_code(code: u64) -> ExternCallResponse {
2090    if get_invoke_failure_code(code).is_some() {
2091        // Querying the exchange rates should never produce a failure response code.
2092        unsafe { crate::hint::unreachable_unchecked() }
2093    } else {
2094        // Map out the 3 bytes encoding the return value index.
2095        let return_value_index = NonZeroU32::new((code >> 40) as u32).unwrap_abort();
2096        ExternCallResponse::new(return_value_index)
2097    }
2098}
2099
2100/// Decode the contract module reference response code.
2101///
2102/// - Success if the last 5 bytes are all zero:
2103///   - the first 3 bytes encodes the return value index.
2104/// - In case of failure the 4th byte is used, and encodes the environment
2105///   failure where:
2106///    - '0x03' encodes missing contract.
2107#[cfg(feature = "p7")]
2108fn parse_query_contract_module_reference_response_code(
2109    code: u64,
2110) -> Result<ExternCallResponse, QueryContractModuleReferenceError> {
2111    if let Some(error_code) = get_invoke_failure_code(code) {
2112        if error_code == 0x03 {
2113            Err(QueryContractModuleReferenceError)
2114        } else {
2115            unsafe { crate::hint::unreachable_unchecked() }
2116        }
2117    } else {
2118        // Map out the 3 bytes encoding the return value index.
2119        let return_value_index = NonZeroU32::new((code >> 40) as u32).unwrap_abort();
2120        Ok(ExternCallResponse::new(return_value_index))
2121    }
2122}
2123
2124/// Decode the contract name response code.
2125///
2126/// - Success if the last 5 bytes are all zero:
2127///   - the first 3 bytes encodes the return value index.
2128/// - In case of failure the 4th byte is used, and encodes the environment
2129///   failure where:
2130///    - '0x03' encodes missing contract.
2131#[cfg(feature = "p7")]
2132fn parse_query_contract_name_response_code(
2133    code: u64,
2134) -> Result<OwnedContractName, QueryContractNameError> {
2135    if let Some(error_code) = get_invoke_failure_code(code) {
2136        if error_code == 0x03 {
2137            Err(QueryContractNameError)
2138        } else {
2139            unsafe { crate::hint::unreachable_unchecked() }
2140        }
2141    } else {
2142        // Map out the 3 bytes encoding the return value index.
2143        let return_value_index = (code >> 40) as u32;
2144        let name = unsafe {
2145            let name_size = prims::get_parameter_size(return_value_index);
2146            if name_size < 0 {
2147                crate::hint::unreachable_unchecked()
2148            }
2149            let mut buf = vec![0; name_size as usize];
2150            prims::get_parameter_section(return_value_index, buf.as_mut_ptr(), name_size as u32, 0);
2151            String::from_utf8_unchecked(buf)
2152        };
2153        Ok(OwnedContractName::new_unchecked(name))
2154    }
2155}
2156
2157/// Helper factoring out the common behaviour of invoke_transfer for the two
2158/// extern hosts below.
2159fn invoke_transfer_worker(receiver: &AccountAddress, amount: Amount) -> TransferResult {
2160    let mut bytes: MaybeUninit<[u8; ACCOUNT_ADDRESS_SIZE + 8]> = MaybeUninit::uninit();
2161    let data = unsafe {
2162        (bytes.as_mut_ptr() as *mut u8).copy_from_nonoverlapping(
2163            receiver.as_ref() as *const [u8; ACCOUNT_ADDRESS_SIZE] as *const u8,
2164            ACCOUNT_ADDRESS_SIZE,
2165        );
2166        (bytes.as_mut_ptr() as *mut u8).add(ACCOUNT_ADDRESS_SIZE).copy_from_nonoverlapping(
2167            &amount.micro_ccd.to_le_bytes() as *const [u8; 8] as *const u8,
2168            8,
2169        );
2170        bytes.assume_init()
2171    };
2172    let response = unsafe {
2173        prims::invoke(INVOKE_TRANSFER_TAG, data.as_ptr(), (ACCOUNT_ADDRESS_SIZE + 8) as u32)
2174    };
2175    parse_transfer_response_code(response)
2176}
2177
2178/// A helper that constructs the parameter to invoke_contract.
2179fn invoke_contract_construct_parameter(
2180    to: &ContractAddress,
2181    parameter: Parameter,
2182    method: EntrypointName,
2183    amount: Amount,
2184) -> Vec<u8> {
2185    let mut data =
2186        Vec::with_capacity(16 + parameter.as_ref().len() + 2 + method.size() as usize + 2 + 8);
2187    let mut cursor = Cursor::new(&mut data);
2188    to.serial(&mut cursor).unwrap_abort();
2189    parameter.serial(&mut cursor).unwrap_abort();
2190    method.serial(&mut cursor).unwrap_abort();
2191    amount.serial(&mut cursor).unwrap_abort();
2192    data
2193}
2194
2195/// Helper factoring out the common behaviour of account_balance for the
2196/// two extern hosts below.
2197fn query_account_balance_worker(address: &AccountAddress) -> QueryAccountBalanceResult {
2198    let response = unsafe {
2199        prims::invoke(
2200            INVOKE_QUERY_ACCOUNT_BALANCE_TAG,
2201            AsRef::<[u8]>::as_ref(&address).as_ptr(),
2202            32,
2203        )
2204    };
2205    let mut return_value = parse_query_account_balance_response_code(response)?;
2206    Ok(AccountBalance::deserial(&mut return_value).unwrap_abort())
2207}
2208
2209/// Helper factoring out the common behaviour of contract_balance for the
2210/// two extern hosts below.
2211fn query_contract_balance_worker(address: &ContractAddress) -> QueryContractBalanceResult {
2212    let data = [address.index.to_le_bytes(), address.subindex.to_le_bytes()];
2213    let response =
2214        unsafe { prims::invoke(INVOKE_QUERY_CONTRACT_BALANCE_TAG, data.as_ptr() as *const u8, 16) };
2215    let mut return_value = parse_query_contract_balance_response_code(response)?;
2216    Ok(Amount::deserial(&mut return_value).unwrap_abort())
2217}
2218
2219/// Helper factoring out the common behaviour of exchange_rates for the
2220/// two extern hosts below.
2221fn query_exchange_rates_worker() -> ExchangeRates {
2222    let response_code = unsafe { prims::invoke(INVOKE_QUERY_EXCHANGE_RATES_TAG, [].as_ptr(), 0) };
2223
2224    let mut response = parse_query_exchange_rates_response_code(response_code);
2225    ExchangeRates::deserial(&mut response).unwrap_abort()
2226}
2227
2228/// Helper factoring out the common behaviour of `account_public_keys` for the
2229/// two extern hosts below.
2230fn query_account_public_keys_worker(address: AccountAddress) -> QueryAccountPublicKeysResult {
2231    let data: &[u8] = address.as_ref();
2232    let response =
2233        unsafe { prims::invoke(INVOKE_QUERY_ACCOUNT_PUBLIC_KEYS_TAG, data.as_ptr(), 32) };
2234    let mut return_value = parse_query_account_public_keys_response_code(response)?;
2235    Ok(crate::AccountPublicKeys::deserial(&mut return_value).unwrap_abort())
2236}
2237
2238fn check_account_signature_worker(
2239    address: AccountAddress,
2240    signatures: &AccountSignatures,
2241    data: &[u8],
2242) -> CheckAccountSignatureResult {
2243    let mut buffer = address.0.to_vec();
2244    (data.len() as u32).serial(&mut buffer).unwrap_abort();
2245    buffer.extend_from_slice(data);
2246    signatures.serial(&mut buffer).unwrap_abort();
2247
2248    let response = unsafe {
2249        prims::invoke(INVOKE_CHECK_ACCOUNT_SIGNATURE_TAG, buffer.as_ptr(), buffer.len() as u32)
2250    };
2251    // Be explicit that the buffer must survive up to here.
2252    drop(buffer);
2253    parse_check_account_signature_response_code(response)
2254}
2255
2256/// Helper factoring out the common behaviour of contract_module_reference for
2257/// the two extern hosts below.
2258#[cfg(feature = "p7")]
2259fn query_contract_module_reference_worker(
2260    address: &ContractAddress,
2261) -> QueryContractModuleReferenceResult {
2262    let data = [address.index.to_le_bytes(), address.subindex.to_le_bytes()];
2263    let response = unsafe {
2264        prims::invoke(INVOKE_QUERY_CONTRACT_MODULE_REFERENCE_TAG, data.as_ptr() as *const u8, 16)
2265    };
2266    let mut return_value = parse_query_contract_module_reference_response_code(response)?;
2267    Ok(ModuleReference::deserial(&mut return_value).unwrap_abort())
2268}
2269
2270/// Helper factoring out the common behaviour of contract_name for
2271/// the two extern hosts below.
2272#[cfg(feature = "p7")]
2273fn query_contract_name_worker(address: &ContractAddress) -> QueryContractNameResult {
2274    let data = [address.index.to_le_bytes(), address.subindex.to_le_bytes()];
2275    let response =
2276        unsafe { prims::invoke(INVOKE_QUERY_CONTRACT_NAME_TAG, data.as_ptr() as *const u8, 16) };
2277    parse_query_contract_name_response_code(response)
2278}
2279
2280impl<S> StateBuilder<S>
2281where
2282    S: HasStateApi,
2283{
2284    /// Open a new state_builder. Only a single instance of the state_builder
2285    /// should exist during contract execution, thus this should only be
2286    /// called at the very beginning of execution.
2287    pub fn open(state: S) -> Self {
2288        Self {
2289            state_api: state,
2290        }
2291    }
2292
2293    /// Provide clone of [`HasStateApi`] instance and new key prefix
2294    /// for any container-like type wishing to store its data on blockchain.
2295    ///
2296    /// Container types [`StateBox`], [`StateSet`], [`StateMap`] provided by
2297    /// Concordium SDK are created using this method internally.
2298    /// Contract developers can use it to implement their own
2299    /// containers.
2300    ///
2301    /// Any container type which provides more ergonomic APIs and behavior atop
2302    /// raw storage is expected to have two items:
2303    /// * Handle-like object which implements [`HasStateApi`]. It provides
2304    ///   access to contract VM features, including storage management. This
2305    ///   object is not serialized, instead it's provided by executon
2306    ///   environment. Can be treated as handle, relatively cheap to clone.
2307    /// * Prefix for keys of all entries managed by new container. Storage of
2308    ///   Concordium contract behaves like flat key-value dictionary, so each
2309    ///   container must have unique prefix for the keys of any entries it
2310    ///   stores to avoid collisions with other containers. This prefix is
2311    ///   serialized as (part of) persistent representation of container.
2312    ///
2313    /// # Returns
2314    /// A pair of:
2315    /// * Object which gives access to low-level storage API. Same as the one
2316    ///   held by [`StateBuilder`] itself and usually the one which refers to
2317    ///   current contract storage.
2318    /// * New unique key prefix for this container.
2319    #[must_use]
2320    pub fn new_state_container(&mut self) -> (S, [u8; 8]) {
2321        (self.state_api.clone(), self.get_and_update_item_prefix())
2322    }
2323
2324    /// Create a new empty [`StateMap`].
2325    pub fn new_map<K, V>(&mut self) -> StateMap<K, V, S> {
2326        let (state_api, prefix) = self.new_state_container();
2327        StateMap::open(state_api, prefix)
2328    }
2329
2330    /// Create a new empty [`StateSet`].
2331    pub fn new_set<T>(&mut self) -> StateSet<T, S> {
2332        let (state_api, prefix) = self.new_state_container();
2333        StateSet::open(state_api, prefix)
2334    }
2335
2336    /// Create a new [`StateBox`] and insert the `value` into the state.
2337    /// This stores the serialized value in the contract state. Thus **if the
2338    /// `StateBox` is dropped without calling [`delete`](StateBox::delete)
2339    /// then the value will remain in contract state, leading to a space leak.**
2340    ///
2341    /// Note that this dropping can happen implicitly via assignment. For
2342    /// example,
2343    ///
2344    /// ```no_run
2345    /// # use concordium_std::*;
2346    /// struct MyState<S: HasStateApi> {
2347    ///     inner: StateBox<u64, S>,
2348    /// }
2349    /// fn incorrect_replace<S: HasStateApi>(
2350    ///     state_builder: &mut StateBuilder<S>,
2351    ///     state: &mut MyState<S>,
2352    /// ) {
2353    ///     // The following is incorrect. The old value of `inner` is not properly deleted.
2354    ///     // from the state.
2355    ///     state.inner = state_builder.new_box(0); // ⚠️
2356    /// }
2357    /// ```
2358    /// Instead, the old value should be manually deleted.
2359    /// ```no_run
2360    /// # use concordium_std::*;
2361    /// # struct MyState<S: HasStateApi> {
2362    /// #    inner: StateBox<u64, S>
2363    /// # }
2364    /// fn correct_replace<S: HasStateApi>(
2365    ///     state_builder: &mut StateBuilder<S>,
2366    ///     state: &mut MyState<S>,
2367    /// ) {
2368    ///     let old_box = mem::replace(&mut state.inner, state_builder.new_box(0));
2369    ///     old_box.delete()
2370    /// }
2371    /// ```
2372    #[must_use]
2373    pub fn new_box<T: Serial>(&mut self, value: T) -> StateBox<T, S> {
2374        let (state_api, prefix) = self.new_state_container();
2375
2376        // Insert the value into the state
2377        let mut state_entry = self.state_api.create_entry(&prefix).unwrap_abort();
2378        value.serial(&mut state_entry).unwrap_abort();
2379        StateBox::new(value, state_api, state_entry)
2380    }
2381
2382    fn get_and_update_item_prefix(&mut self) -> [u8; 8] {
2383        // Get the next prefix or insert and use the initial one.
2384        // Unwrapping is safe when using the high-level API because it is not possible
2385        // to get an iterator that locks this entry.
2386        let mut next_collection_prefix_entry = self
2387            .state_api
2388            .entry(NEXT_ITEM_PREFIX_KEY)
2389            .or_insert_raw(&INITIAL_NEXT_ITEM_PREFIX)
2390            .unwrap_abort();
2391
2392        // Get the next collection prefix
2393        let collection_prefix = next_collection_prefix_entry.read_u64().unwrap_abort(); // Unwrapping is safe if only using the high-level API.
2394
2395        // Rewind state entry position.
2396        next_collection_prefix_entry.move_to_start();
2397
2398        // Increment the collection prefix
2399        next_collection_prefix_entry.write_u64(collection_prefix + 1).unwrap_abort(); // Writing to state cannot fail.
2400
2401        collection_prefix.to_le_bytes()
2402    }
2403}
2404
2405impl StateBuilder<StateApi> {
2406    /// Create a new empty [`StateBTreeSet`](crate::StateBTreeSet).
2407    pub fn new_btree_set<K>(&mut self) -> state_btree::StateBTreeSet<K> {
2408        let (state_api, prefix) = self.new_state_container();
2409        state_btree::StateBTreeSet::new(state_api, prefix)
2410    }
2411
2412    /// Create a new empty [`StateBTreeMap`](crate::StateBTreeMap).
2413    pub fn new_btree_map<K, V>(&mut self) -> state_btree::StateBTreeMap<K, V> {
2414        state_btree::StateBTreeMap {
2415            key_value: self.new_map(),
2416            key_order: self.new_btree_set(),
2417        }
2418    }
2419
2420    /// Create a new empty [`StateBTreeSet`](crate::StateBTreeSet), setting the
2421    /// minimum degree `M` of the B-Tree explicitly. `M` must be 2 or higher
2422    /// otherwise constructing the B-Tree results in aborting.
2423    pub fn new_btree_set_degree<const M: usize, K>(&mut self) -> state_btree::StateBTreeSet<K, M> {
2424        if M >= 2 {
2425            let (state_api, prefix) = self.new_state_container();
2426            state_btree::StateBTreeSet::new(state_api, prefix)
2427        } else {
2428            crate::fail!(
2429                "Invalid minimum degree used for StateBTreeSet, must be >=2 instead got {}",
2430                M
2431            )
2432        }
2433    }
2434
2435    /// Create a new empty [`StateBTreeMap`](crate::StateBTreeMap), setting the
2436    /// minimum degree `M` of the B-Tree explicitly. `M` must be 2 or higher
2437    /// otherwise constructing the B-Tree results in aborting.
2438    pub fn new_btree_map_degree<const M: usize, K, V>(
2439        &mut self,
2440    ) -> state_btree::StateBTreeMap<K, V, M> {
2441        if M >= 2 {
2442            state_btree::StateBTreeMap {
2443                key_value: self.new_map(),
2444                key_order: self.new_btree_set_degree(),
2445            }
2446        } else {
2447            crate::fail!(
2448                "Invalid minimum degree used for StateBTreeMap, must be >=2 instead got {}",
2449                M
2450            )
2451        }
2452    }
2453}
2454
2455impl<S> HasHost<S> for ExternHost<S>
2456where
2457    S: Serial + DeserialWithState<ExternStateApi>,
2458{
2459    type ReturnValueType = ExternCallResponse;
2460    type StateApiType = ExternStateApi;
2461
2462    fn invoke_transfer(&self, receiver: &AccountAddress, amount: Amount) -> TransferResult {
2463        invoke_transfer_worker(receiver, amount)
2464    }
2465
2466    fn invoke_contract_raw(
2467        &mut self,
2468        to: &ContractAddress,
2469        parameter: Parameter,
2470        method: EntrypointName,
2471        amount: Amount,
2472    ) -> CallContractResult<Self::ReturnValueType> {
2473        let data = invoke_contract_construct_parameter(to, parameter, method, amount);
2474        let len = data.len();
2475        // save the state before the out-call to reflect any changes we might have done.
2476        // this is not optimal, and ideally we'd keep track of changes. But that is more
2477        // error prone for the programmer.
2478        self.commit_state();
2479        let response = unsafe { prims::invoke(INVOKE_CALL_TAG, data.as_ptr(), len as u32) };
2480        let (state_modified, res) = parse_call_response_code(response)?;
2481        if state_modified {
2482            // The state of the contract changed as a result of the call.
2483            // So we refresh it.
2484            if let Ok(new_state) = S::deserial_with_state(
2485                &self.state_builder.state_api,
2486                &mut self.state_builder.state_api.lookup_entry(&[]).unwrap_abort(),
2487            ) {
2488                self.state = new_state;
2489            } else {
2490                crate::trap()
2491            }
2492        }
2493        Ok((state_modified, res))
2494    }
2495
2496    fn invoke_contract_raw_read_only(
2497        &self,
2498        to: &ContractAddress,
2499        parameter: Parameter,
2500        method: EntrypointName,
2501        amount: Amount,
2502    ) -> ReadOnlyCallContractResult<Self::ReturnValueType> {
2503        let data = invoke_contract_construct_parameter(to, parameter, method, amount);
2504        let len = data.len();
2505        let response = unsafe { prims::invoke(INVOKE_CALL_TAG, data.as_ptr(), len as u32) };
2506        let (state_modified, res) = parse_call_response_code(response)?;
2507        if state_modified {
2508            crate::trap()
2509        } else {
2510            Ok(res)
2511        }
2512    }
2513
2514    #[inline(always)]
2515    fn account_balance(&self, address: AccountAddress) -> QueryAccountBalanceResult {
2516        query_account_balance_worker(&address)
2517    }
2518
2519    #[inline(always)]
2520    fn contract_balance(&self, address: ContractAddress) -> QueryContractBalanceResult {
2521        query_contract_balance_worker(&address)
2522    }
2523
2524    #[inline(always)]
2525    fn exchange_rates(&self) -> ExchangeRates { query_exchange_rates_worker() }
2526
2527    fn upgrade(&mut self, module: ModuleReference) -> UpgradeResult {
2528        let response = unsafe { prims::upgrade(module.as_ref().as_ptr()) };
2529        parse_upgrade_response_code(response)
2530    }
2531
2532    fn account_public_keys(&self, address: AccountAddress) -> QueryAccountPublicKeysResult {
2533        query_account_public_keys_worker(address)
2534    }
2535
2536    fn check_account_signature(
2537        &self,
2538        address: AccountAddress,
2539        signatures: &AccountSignatures,
2540        data: &[u8],
2541    ) -> CheckAccountSignatureResult {
2542        check_account_signature_worker(address, signatures, data)
2543    }
2544
2545    #[cfg(feature = "p7")]
2546    #[inline(always)]
2547    fn contract_module_reference(
2548        &self,
2549        address: ContractAddress,
2550    ) -> QueryContractModuleReferenceResult {
2551        query_contract_module_reference_worker(&address)
2552    }
2553
2554    #[cfg(feature = "p7")]
2555    #[inline(always)]
2556    fn contract_name(&self, address: ContractAddress) -> QueryContractNameResult {
2557        query_contract_name_worker(&address)
2558    }
2559
2560    fn state(&self) -> &S { &self.state }
2561
2562    fn state_mut(&mut self) -> &mut S { &mut self.state }
2563
2564    fn commit_state(&mut self) {
2565        let mut root_entry = self.state_builder.state_api.lookup_entry(&[]).unwrap_abort();
2566        self.state.serial(&mut root_entry).unwrap_abort();
2567        let new_state_size = root_entry.size().unwrap_abort();
2568        root_entry.truncate(new_state_size).unwrap_abort();
2569    }
2570
2571    #[inline(always)]
2572    fn self_balance(&self) -> Amount {
2573        Amount::from_micro_ccd(unsafe { prims::get_receive_self_balance() })
2574    }
2575
2576    #[inline(always)]
2577    fn state_builder(&mut self) -> &mut StateBuilder<Self::StateApiType> { &mut self.state_builder }
2578
2579    #[inline(always)]
2580    fn state_and_builder(&mut self) -> (&mut S, &mut StateBuilder<Self::StateApiType>) {
2581        (&mut self.state, &mut self.state_builder)
2582    }
2583}
2584impl HasHost<ExternStateApi> for ExternLowLevelHost {
2585    type ReturnValueType = ExternCallResponse;
2586    type StateApiType = ExternStateApi;
2587
2588    #[inline(always)]
2589    fn invoke_transfer(&self, receiver: &AccountAddress, amount: Amount) -> TransferResult {
2590        invoke_transfer_worker(receiver, amount)
2591    }
2592
2593    fn invoke_contract_raw(
2594        &mut self,
2595        to: &ContractAddress,
2596        parameter: Parameter,
2597        method: EntrypointName,
2598        amount: Amount,
2599    ) -> CallContractResult<Self::ReturnValueType> {
2600        let data = invoke_contract_construct_parameter(to, parameter, method, amount);
2601        let len = data.len();
2602        let response = unsafe { prims::invoke(INVOKE_CALL_TAG, data.as_ptr(), len as u32) };
2603        parse_call_response_code(response)
2604    }
2605
2606    #[inline(always)]
2607    fn account_balance(&self, address: AccountAddress) -> QueryAccountBalanceResult {
2608        query_account_balance_worker(&address)
2609    }
2610
2611    #[inline(always)]
2612    fn contract_balance(&self, address: ContractAddress) -> QueryContractBalanceResult {
2613        query_contract_balance_worker(&address)
2614    }
2615
2616    #[inline(always)]
2617    fn exchange_rates(&self) -> ExchangeRates { query_exchange_rates_worker() }
2618
2619    fn upgrade(&mut self, module: ModuleReference) -> UpgradeResult {
2620        let response = unsafe { prims::upgrade(module.as_ref().as_ptr()) };
2621        parse_upgrade_response_code(response)
2622    }
2623
2624    fn account_public_keys(&self, address: AccountAddress) -> QueryAccountPublicKeysResult {
2625        query_account_public_keys_worker(address)
2626    }
2627
2628    fn check_account_signature(
2629        &self,
2630        address: AccountAddress,
2631        signatures: &AccountSignatures,
2632        data: &[u8],
2633    ) -> CheckAccountSignatureResult {
2634        check_account_signature_worker(address, signatures, data)
2635    }
2636
2637    #[cfg(feature = "p7")]
2638    #[inline(always)]
2639    fn contract_module_reference(
2640        &self,
2641        address: ContractAddress,
2642    ) -> QueryContractModuleReferenceResult {
2643        query_contract_module_reference_worker(&address)
2644    }
2645
2646    #[cfg(feature = "p7")]
2647    #[inline(always)]
2648    fn contract_name(&self, address: ContractAddress) -> QueryContractNameResult {
2649        query_contract_name_worker(&address)
2650    }
2651
2652    #[inline(always)]
2653    fn state(&self) -> &ExternStateApi { &self.state_api }
2654
2655    #[inline(always)]
2656    fn state_mut(&mut self) -> &mut ExternStateApi { &mut self.state_api }
2657
2658    #[inline(always)]
2659    fn commit_state(&mut self) {
2660        // do nothing since the low level host does not maintain any state
2661    }
2662
2663    #[inline(always)]
2664    fn self_balance(&self) -> Amount {
2665        Amount::from_micro_ccd(unsafe { prims::get_receive_self_balance() })
2666    }
2667
2668    #[inline(always)]
2669    fn state_builder(&mut self) -> &mut StateBuilder<Self::StateApiType> { &mut self.state_builder }
2670
2671    #[inline(always)]
2672    fn state_and_builder(
2673        &mut self,
2674    ) -> (&mut ExternStateApi, &mut StateBuilder<Self::StateApiType>) {
2675        (&mut self.state_api, &mut self.state_builder)
2676    }
2677
2678    fn invoke_contract_raw_read_only(
2679        &self,
2680        to: &ContractAddress,
2681        parameter: Parameter<'_>,
2682        method: EntrypointName<'_>,
2683        amount: Amount,
2684    ) -> ReadOnlyCallContractResult<Self::ReturnValueType> {
2685        let data = invoke_contract_construct_parameter(to, parameter, method, amount);
2686        let len = data.len();
2687        let response = unsafe { prims::invoke(INVOKE_CALL_TAG, data.as_ptr(), len as u32) };
2688        let (state_modified, res) = parse_call_response_code(response)?;
2689        if state_modified {
2690            crate::trap()
2691        } else {
2692            Ok(res)
2693        }
2694    }
2695}
2696
2697impl HasCryptoPrimitives for ExternCryptoPrimitives {
2698    fn verify_ed25519_signature(
2699        &self,
2700        public_key: PublicKeyEd25519,
2701        signature: SignatureEd25519,
2702        message: &[u8],
2703    ) -> bool {
2704        let res = unsafe {
2705            prims::verify_ed25519_signature(
2706                public_key.0.as_ptr(),
2707                signature.0.as_ptr(),
2708                message.as_ptr(),
2709                message.len() as u32,
2710            )
2711        };
2712        res == 1
2713    }
2714
2715    fn verify_ecdsa_secp256k1_signature(
2716        &self,
2717        public_key: PublicKeyEcdsaSecp256k1,
2718        signature: SignatureEcdsaSecp256k1,
2719        message_hash: [u8; 32],
2720    ) -> bool {
2721        let res = unsafe {
2722            prims::verify_ecdsa_secp256k1_signature(
2723                public_key.0.as_ptr(),
2724                signature.0.as_ptr(),
2725                message_hash.as_ptr(),
2726            )
2727        };
2728        res == 1
2729    }
2730
2731    fn hash_sha2_256(&self, data: &[u8]) -> HashSha2256 {
2732        let mut output: MaybeUninit<[u8; 32]> = MaybeUninit::uninit();
2733        unsafe {
2734            prims::hash_sha2_256(data.as_ptr(), data.len() as u32, output.as_mut_ptr() as *mut u8);
2735            HashSha2256(output.assume_init())
2736        }
2737    }
2738
2739    fn hash_sha3_256(&self, data: &[u8]) -> HashSha3256 {
2740        let mut output: MaybeUninit<[u8; 32]> = MaybeUninit::uninit();
2741        unsafe {
2742            prims::hash_sha3_256(data.as_ptr(), data.len() as u32, output.as_mut_ptr() as *mut u8);
2743            HashSha3256(output.assume_init())
2744        }
2745    }
2746
2747    fn hash_keccak_256(&self, data: &[u8]) -> HashKeccak256 {
2748        let mut output: MaybeUninit<[u8; 32]> = MaybeUninit::uninit();
2749        unsafe {
2750            prims::hash_keccak_256(
2751                data.as_ptr(),
2752                data.len() as u32,
2753                output.as_mut_ptr() as *mut u8,
2754            );
2755            HashKeccak256(output.assume_init())
2756        }
2757    }
2758}
2759
2760/// # Trait implementations for the init context
2761impl HasInitContext for ExternContext<crate::types::ExternInitContext> {
2762    type InitData = ();
2763
2764    /// Create a new init context by using an external call.
2765    fn open(_: Self::InitData) -> Self { ExternContext::default() }
2766
2767    #[inline(always)]
2768    fn init_origin(&self) -> AccountAddress {
2769        let mut bytes: MaybeUninit<[u8; ACCOUNT_ADDRESS_SIZE]> = MaybeUninit::uninit();
2770        let ptr = bytes.as_mut_ptr();
2771        let address = unsafe {
2772            prims::get_init_origin(ptr as *mut u8);
2773            bytes.assume_init()
2774        };
2775        AccountAddress(address)
2776    }
2777}
2778
2779/// # Trait implementations for the receive context
2780impl HasReceiveContext for ExternContext<crate::types::ExternReceiveContext> {
2781    type ReceiveData = ();
2782
2783    /// Create a new receive context
2784    fn open(_: Self::ReceiveData) -> Self { ExternContext::default() }
2785
2786    #[inline(always)]
2787    fn invoker(&self) -> AccountAddress {
2788        let mut bytes: MaybeUninit<[u8; ACCOUNT_ADDRESS_SIZE]> = MaybeUninit::uninit();
2789        let ptr = bytes.as_mut_ptr();
2790        let address = unsafe {
2791            prims::get_receive_invoker(ptr as *mut u8);
2792            bytes.assume_init()
2793        };
2794        AccountAddress(address)
2795    }
2796
2797    #[inline(always)]
2798    fn self_address(&self) -> ContractAddress {
2799        let mut bytes: MaybeUninit<[u8; 16]> = MaybeUninit::uninit();
2800        let ptr = bytes.as_mut_ptr();
2801        let address = unsafe {
2802            prims::get_receive_self_address(ptr as *mut u8);
2803            bytes.assume_init()
2804        };
2805        match from_bytes(&address) {
2806            Ok(v) => v,
2807            Err(_) => crate::trap(),
2808        }
2809    }
2810
2811    #[inline(always)]
2812    fn sender(&self) -> Address {
2813        let mut bytes: MaybeUninit<[u8; 33]> = MaybeUninit::uninit();
2814        let ptr = bytes.as_mut_ptr() as *mut u8;
2815        unsafe {
2816            prims::get_receive_sender(ptr);
2817            let tag = *ptr;
2818            match tag {
2819                0u8 => {
2820                    match from_bytes(core::slice::from_raw_parts(ptr.add(1), ACCOUNT_ADDRESS_SIZE))
2821                    {
2822                        Ok(v) => Address::Account(v),
2823                        Err(_) => crate::trap(),
2824                    }
2825                }
2826                1u8 => match from_bytes(core::slice::from_raw_parts(ptr.add(1), 16)) {
2827                    Ok(v) => Address::Contract(v),
2828                    Err(_) => crate::trap(),
2829                },
2830                _ => crate::trap(), // unreachable!("Host violated precondition."),
2831            }
2832        }
2833    }
2834
2835    #[inline(always)]
2836    fn owner(&self) -> AccountAddress {
2837        let mut bytes: MaybeUninit<[u8; ACCOUNT_ADDRESS_SIZE]> = MaybeUninit::uninit();
2838        let ptr = bytes.as_mut_ptr();
2839        let address = unsafe {
2840            prims::get_receive_owner(ptr as *mut u8);
2841            bytes.assume_init()
2842        };
2843        AccountAddress(address)
2844    }
2845
2846    fn named_entrypoint(&self) -> OwnedEntrypointName {
2847        let mut data = crate::vec![0u8; unsafe { prims::get_receive_entrypoint_size() as usize }];
2848        unsafe { prims::get_receive_entrypoint(data.as_mut_ptr()) };
2849        OwnedEntrypointName::new_unchecked(unsafe { String::from_utf8_unchecked(data) })
2850    }
2851}
2852
2853/// #Implementations of the logger.
2854
2855impl HasLogger for Logger {
2856    #[inline(always)]
2857    fn init() -> Self {
2858        Self {
2859            _private: (),
2860        }
2861    }
2862
2863    fn log_raw(&mut self, event: &[u8]) -> Result<(), LogError> {
2864        let res = unsafe { prims::log_event(event.as_ptr(), event.len() as u32) };
2865        match res {
2866            1 => Ok(()),
2867            0 => Err(LogError::Full),
2868            _ => Err(LogError::Malformed),
2869        }
2870    }
2871}
2872
2873/// Allocates a Vec of bytes prepended with its length as a `u32` into memory,
2874/// and prevents them from being dropped. Returns the pointer.
2875/// Used to pass bytes from a Wasm module to its host.
2876#[doc(hidden)]
2877pub fn put_in_memory(input: &[u8]) -> *mut u8 {
2878    let bytes_length = input.len() as u32;
2879    let mut bytes = to_bytes(&bytes_length);
2880    bytes.extend_from_slice(input);
2881    let ptr = bytes.as_mut_ptr();
2882    #[cfg(feature = "std")]
2883    ::std::mem::forget(bytes);
2884    #[cfg(not(feature = "std"))]
2885    core::mem::forget(bytes);
2886    ptr
2887}
2888
2889impl<A, E> UnwrapAbort for Result<A, E> {
2890    type Unwrap = A;
2891
2892    #[inline]
2893    fn unwrap_abort(self) -> Self::Unwrap {
2894        match self {
2895            Ok(x) => x,
2896            Err(_) => crate::trap(),
2897        }
2898    }
2899}
2900
2901impl<A, E: fmt::Debug> ExpectReport for Result<A, E> {
2902    type Unwrap = A;
2903
2904    fn expect_report(self, msg: &str) -> Self::Unwrap {
2905        match self {
2906            Ok(x) => x,
2907            Err(e) => crate::fail!("{}: {:?}", msg, e),
2908        }
2909    }
2910}
2911
2912impl<A: fmt::Debug, E> ExpectErrReport for Result<A, E> {
2913    type Unwrap = E;
2914
2915    fn expect_err_report(self, msg: &str) -> Self::Unwrap {
2916        match self {
2917            Ok(a) => crate::fail!("{}: {:?}", msg, a),
2918            Err(e) => e,
2919        }
2920    }
2921}
2922
2923impl<A> UnwrapAbort for Option<A> {
2924    type Unwrap = A;
2925
2926    #[inline(always)]
2927    #[allow(clippy::redundant_closure)]
2928    // The redundant_closure here is needed since there is an implicit coercion from
2929    // ! to A. This does not happen if we just use unwrap_or_else(crate::trap).
2930    fn unwrap_abort(self) -> Self::Unwrap { self.unwrap_or_else(|| crate::trap()) }
2931}
2932
2933impl<A> ExpectReport for Option<A> {
2934    type Unwrap = A;
2935
2936    fn expect_report(self, msg: &str) -> Self::Unwrap {
2937        match self {
2938            Some(v) => v,
2939            None => crate::fail!("{}", msg),
2940        }
2941    }
2942}
2943
2944impl<A: fmt::Debug> ExpectNoneReport for Option<A> {
2945    fn expect_none_report(self, msg: &str) {
2946        if let Some(x) = self {
2947            crate::fail!("{}: {:?}", msg, x)
2948        }
2949    }
2950}
2951
2952/// Blanket implementation of [DeserialWithState] for any [Deserial] types,
2953/// which simply does not use the state argument.
2954impl<D: Deserial, S: HasStateApi> DeserialWithState<S> for D {
2955    #[inline(always)]
2956    fn deserial_with_state<R: Read>(_state: &S, source: &mut R) -> ParseResult<Self> {
2957        Self::deserial(source)
2958    }
2959}
2960
2961/// Blanket implementation of [DeserialCtxWithState] for any [DeserialCtx]
2962/// types, which simply does not use the state argument.
2963impl<D: DeserialCtx, S: HasStateApi> DeserialCtxWithState<S> for D {
2964    #[inline(always)]
2965    fn deserial_ctx_with_state<R: Read>(
2966        size_length: schema::SizeLength,
2967        ensure_ordered: bool,
2968        _state: &S,
2969        source: &mut R,
2970    ) -> ParseResult<Self> {
2971        Self::deserial_ctx(size_length, ensure_ordered, source)
2972    }
2973}
2974
2975impl<K, V, S> DeserialWithState<S> for StateMap<K, V, S>
2976where
2977    S: HasStateApi,
2978{
2979    fn deserial_with_state<R: Read>(state: &S, source: &mut R) -> ParseResult<Self> {
2980        source.read_array().map(|map_prefix| StateMap::open(state.clone(), map_prefix))
2981    }
2982}
2983
2984impl<T, S> DeserialWithState<S> for StateSet<T, S>
2985where
2986    S: HasStateApi,
2987    T: Serial + DeserialWithState<S>,
2988{
2989    fn deserial_with_state<R: Read>(state: &S, source: &mut R) -> ParseResult<Self> {
2990        source.read_array().map(|set_prefix| StateSet::open(state.clone(), set_prefix))
2991    }
2992}
2993
2994impl<T, S> DeserialWithState<S> for StateBox<T, S>
2995where
2996    S: HasStateApi,
2997    T: Serial + DeserialWithState<S>,
2998{
2999    fn deserial_with_state<R: Read>(state: &S, source: &mut R) -> ParseResult<Self> {
3000        let prefix = source.read_array()?;
3001        Ok(StateBox {
3002            state_api: state.clone(),
3003            inner:     UnsafeCell::new(StateBoxInner::Reference {
3004                prefix,
3005            }),
3006        })
3007    }
3008}
3009
3010impl<T: Serialize> Deletable for T {
3011    #[inline(always)]
3012    fn delete(self) {} // Types that are Serialize have nothing to delete!
3013}
3014
3015impl<T, S> Deletable for StateBox<T, S>
3016where
3017    T: Serial + DeserialWithState<S> + Deletable,
3018    S: HasStateApi,
3019{
3020    fn delete(mut self) {
3021        // replace the value with a dummy one for which drop is a no-op.
3022        let inner = mem::replace(
3023            &mut self.inner,
3024            UnsafeCell::new(StateBoxInner::Reference {
3025                prefix: [0u8; 8],
3026            }),
3027        );
3028        let (entry, value) = match inner.into_inner() {
3029            StateBoxInner::Loaded {
3030                entry,
3031                value,
3032                ..
3033            } => (entry, value),
3034            StateBoxInner::Reference {
3035                prefix,
3036            } => {
3037                // we load the value first because it might be necessary to delete
3038                // the nested value.
3039                // TODO: This is pretty bad for performance, but we cannot specialize the
3040                // implementation for flat values. Once rust supports specialization we might be
3041                // able to have a more precise implementation for flat values,
3042                // i.e., ones which are Deserial.
3043                let mut entry = self.state_api.lookup_entry(&prefix).unwrap_abort();
3044                let value = T::deserial_with_state(&self.state_api, &mut entry).unwrap_abort();
3045                (entry, value)
3046            }
3047        };
3048        self.state_api.delete_entry(entry).unwrap_abort();
3049        value.delete()
3050    }
3051}
3052
3053impl<T, S> Deletable for StateSet<T, S>
3054where
3055    S: HasStateApi,
3056{
3057    fn delete(mut self) {
3058        // Statesets cannot contain state types (e.g. StateBox), so there is nothing to
3059        // delete, apart from the set itself.
3060
3061        // Unwrapping is safe when only using the high-level API.
3062        self.state_api.delete_prefix(&self.prefix).unwrap_abort();
3063    }
3064}
3065
3066impl<K, V, S> Deletable for StateMap<K, V, S>
3067where
3068    S: HasStateApi,
3069    K: Serialize,
3070    V: Serial + DeserialWithState<S> + Deletable,
3071{
3072    fn delete(mut self) { self.clear(); }
3073}
3074
3075impl Serial for HashSha2256 {
3076    fn serial<W: Write>(&self, out: &mut W) -> Result<(), W::Err> { self.0.serial(out) }
3077}
3078
3079impl Deserial for HashSha2256 {
3080    fn deserial<R: Read>(source: &mut R) -> ParseResult<Self> {
3081        Ok(HashSha2256(Deserial::deserial(source)?))
3082    }
3083}
3084
3085impl schema::SchemaType for HashSha2256 {
3086    fn get_type() -> concordium_contracts_common::schema::Type { schema::Type::ByteArray(32) }
3087}
3088
3089impl Serial for HashSha3256 {
3090    fn serial<W: Write>(&self, out: &mut W) -> Result<(), W::Err> { self.0.serial(out) }
3091}
3092
3093impl Deserial for HashSha3256 {
3094    fn deserial<R: Read>(source: &mut R) -> ParseResult<Self> {
3095        Ok(HashSha3256(Deserial::deserial(source)?))
3096    }
3097}
3098
3099impl schema::SchemaType for HashSha3256 {
3100    fn get_type() -> concordium_contracts_common::schema::Type { schema::Type::ByteArray(32) }
3101}
3102
3103impl Serial for HashKeccak256 {
3104    fn serial<W: Write>(&self, out: &mut W) -> Result<(), W::Err> { self.0.serial(out) }
3105}
3106
3107impl Deserial for HashKeccak256 {
3108    fn deserial<R: Read>(source: &mut R) -> ParseResult<Self> {
3109        Ok(HashKeccak256(Deserial::deserial(source)?))
3110    }
3111}
3112
3113impl schema::SchemaType for HashKeccak256 {
3114    fn get_type() -> concordium_contracts_common::schema::Type { schema::Type::ByteArray(32) }
3115}
3116
3117impl schema::SchemaType for MetadataUrl {
3118    fn get_type() -> schema::Type {
3119        schema::Type::Struct(schema::Fields::Named(crate::vec![
3120            (String::from("url"), schema::Type::String(schema::SizeLength::U16)),
3121            // Use the `HashSha2256` schema to represent `hash` as a hex string.
3122            (String::from("hash"), Option::<HashSha2256>::get_type()),
3123        ]))
3124    }
3125}
3126
3127impl Serial for MetadataUrl {
3128    fn serial<W: Write>(&self, out: &mut W) -> Result<(), W::Err> {
3129        // Serialize url as a string with size_length = 2
3130        let bytes = self.url.as_bytes();
3131        let len = bytes.len() as u16;
3132        len.serial(out)?;
3133        serial_vector_no_length(bytes, out)?;
3134        self.hash.serial(out)
3135    }
3136}
3137
3138impl Deserial for MetadataUrl {
3139    fn deserial<R: Read>(source: &mut R) -> ParseResult<Self> {
3140        // Deserialize url as a string with size_length = 2
3141        let len: u16 = source.get()?;
3142        let bytes = deserial_vector_no_length(source, len as usize)?;
3143        Ok(MetadataUrl {
3144            url:  String::from_utf8(bytes).map_err(|_| ParseError::default())?,
3145            hash: Deserial::deserial(source)?,
3146        })
3147    }
3148}
3149
3150#[cfg(test)]
3151mod tests {
3152
3153    /// Check that you cannot have multiple active entries from a statemap at
3154    /// the same time. See the test file for details.
3155    #[test]
3156    fn statemap_multiple_entries_not_allowed() {
3157        let t = trybuild::TestCases::new();
3158        t.compile_fail("tests/state/map-multiple-entries.rs");
3159    }
3160
3161    #[test]
3162    fn statemap_multiple_state_ref_mut_not_allowed() {
3163        let t = trybuild::TestCases::new();
3164        t.compile_fail("tests/state/map-multiple-state-ref-mut.rs");
3165    }
3166}
3167
3168/// This test module relies on the runtime providing host functions and can only
3169/// be run using `cargo concordium test`.
3170#[cfg(feature = "internal-wasm-test")]
3171mod wasm_test {
3172    use crate::{
3173        claim, claim_eq, concordium_test, to_bytes, Deletable, Deserial, DeserialWithState,
3174        EntryRaw, HasStateApi, HasStateEntry, ParseResult, Serial, StateApi, StateBuilder,
3175        StateError, StateMap, StateSet, INITIAL_NEXT_ITEM_PREFIX,
3176    };
3177
3178    const GENERIC_MAP_PREFIX: u64 = 1;
3179
3180    /// Some helper methods that are used for internal tests.
3181    impl<S> StateBuilder<S>
3182    where
3183        S: HasStateApi,
3184    {
3185        /// Get a value from the generic map.
3186        /// `Some(Err(_))` means that something exists in the state with that
3187        /// key, but it isn't of type `V`.
3188        pub(crate) fn get<K: Serial, V: DeserialWithState<S>>(
3189            &self,
3190            key: K,
3191        ) -> Option<ParseResult<V>> {
3192            let key_with_map_prefix = Self::prepend_generic_map_key(key);
3193
3194            self.state_api
3195                .lookup_entry(&key_with_map_prefix)
3196                .map(|mut entry| V::deserial_with_state(&self.state_api, &mut entry))
3197        }
3198
3199        /// Inserts a value in the generic map.
3200        /// The key and value are serialized before insert.
3201        pub(crate) fn insert<K: Serial, V: Serial>(
3202            &mut self,
3203            key: K,
3204            value: V,
3205        ) -> Result<(), StateError> {
3206            let key_with_map_prefix = Self::prepend_generic_map_key(key);
3207            match self.state_api.entry(key_with_map_prefix) {
3208                EntryRaw::Vacant(vac) => {
3209                    let _ = vac.insert(&value);
3210                }
3211                EntryRaw::Occupied(mut occ) => occ.insert(&value),
3212            }
3213            Ok(())
3214        }
3215
3216        /// Serializes the key and prepends [GENERIC_MAP_PREFIX].
3217        /// This is similar to how [StateMap] works, where a unique prefix is
3218        /// prepended onto keys. Since there is only one generic map, the prefix
3219        /// is a constant.
3220        fn prepend_generic_map_key<K: Serial>(key: K) -> Vec<u8> {
3221            let mut key_with_map_prefix = to_bytes(&GENERIC_MAP_PREFIX);
3222            key_with_map_prefix.append(&mut to_bytes(&key));
3223            key_with_map_prefix
3224        }
3225    }
3226
3227    #[concordium_test]
3228    fn high_level_insert_get() {
3229        let expected_value: u64 = 123123123;
3230        let mut state_builder = StateBuilder::open(StateApi::open());
3231        state_builder.insert(0, expected_value).expect("Insert failed");
3232        let actual_value: u64 = state_builder.get(0).expect("Not found").expect("Not a valid u64");
3233        claim_eq!(expected_value, actual_value);
3234    }
3235
3236    #[concordium_test]
3237    fn low_level_entry() {
3238        let expected_value: u64 = 123123123;
3239        let key = to_bytes(&42u64);
3240        let mut state = StateApi::open();
3241        state
3242            .entry(&key[..])
3243            .or_insert_raw(&to_bytes(&expected_value))
3244            .expect("No iterators, so insertion should work.");
3245
3246        match state.entry(key) {
3247            EntryRaw::Vacant(_) => panic!("Unexpected vacant entry."),
3248            EntryRaw::Occupied(occ) => {
3249                claim_eq!(u64::deserial(&mut occ.get()), Ok(expected_value))
3250            }
3251        }
3252    }
3253
3254    #[concordium_test]
3255    fn high_level_statemap() {
3256        let my_map_key = "my_map";
3257        let mut state_builder = StateBuilder::open(StateApi::open());
3258
3259        let map_to_insert = state_builder.new_map::<String, String>();
3260        state_builder.insert(my_map_key, map_to_insert).expect("Insert failed");
3261
3262        let mut my_map: StateMap<String, String, _> = state_builder
3263            .get(my_map_key)
3264            .expect("Could not get statemap")
3265            .expect("Deserializing statemap failed");
3266        let _ = my_map.insert("abc".to_string(), "hello, world".to_string());
3267        let _ = my_map.insert("def".to_string(), "hallo, Weld".to_string());
3268        let _ = my_map.insert("ghi".to_string(), "hej, verden".to_string());
3269        claim_eq!(*my_map.get(&"abc".to_string()).unwrap(), "hello, world".to_string());
3270
3271        let mut iter = my_map.iter();
3272        let (k1, v1) = iter.next().unwrap();
3273        claim_eq!(*k1, "abc".to_string());
3274        claim_eq!(*v1, "hello, world".to_string());
3275        let (k2, v2) = iter.next().unwrap();
3276        claim_eq!(*k2, "def".to_string());
3277        claim_eq!(*v2, "hallo, Weld".to_string());
3278        let (k3, v3) = iter.next().unwrap();
3279        claim_eq!(*k3, "ghi".to_string());
3280        claim_eq!(*v3, "hej, verden".to_string());
3281        claim!(iter.next().is_none());
3282    }
3283
3284    #[concordium_test]
3285    fn statemap_insert_remove() {
3286        let mut state_builder = StateBuilder::open(StateApi::open());
3287        let mut map = state_builder.new_map();
3288        let value = String::from("hello");
3289        let _ = map.insert(42, value.clone());
3290        claim_eq!(*map.get(&42).unwrap(), value);
3291        map.remove(&42);
3292        claim!(map.get(&42).is_none());
3293    }
3294
3295    #[concordium_test]
3296    fn statemap_clear() {
3297        let mut state_builder = StateBuilder::open(StateApi::open());
3298        let mut map = state_builder.new_map();
3299        let _ = map.insert(1, 2);
3300        let _ = map.insert(2, 3);
3301        let _ = map.insert(3, 4);
3302        map.clear();
3303        claim!(map.is_empty());
3304    }
3305
3306    #[concordium_test]
3307    fn high_level_nested_statemaps() {
3308        let inner_map_key = 0u8;
3309        let key_to_value = 77u8;
3310        let value = 255u8;
3311        let mut state_builder = StateBuilder::open(StateApi::open());
3312        let mut outer_map = state_builder.new_map::<u8, StateMap<u8, u8, _>>();
3313        let mut inner_map = state_builder.new_map::<u8, u8>();
3314
3315        let _ = inner_map.insert(key_to_value, value);
3316        let _ = outer_map.insert(inner_map_key, inner_map);
3317
3318        claim_eq!(*outer_map.get(&inner_map_key).unwrap().get(&key_to_value).unwrap(), value);
3319    }
3320
3321    #[concordium_test]
3322    fn statemap_iter_mut_works() {
3323        let mut state_builder = StateBuilder::open(StateApi::open());
3324        let mut map = state_builder.new_map();
3325        let _ = map.insert(0u8, 1u8);
3326        let _ = map.insert(1u8, 2u8);
3327        let _ = map.insert(2u8, 3u8);
3328        for (_, mut v) in map.iter_mut() {
3329            v.update(|old_value| *old_value += 10);
3330        }
3331        let mut iter = map.iter();
3332        let (k1, v1) = iter.next().unwrap();
3333        claim_eq!(*k1, 0);
3334        claim_eq!(*v1, 11);
3335        let (k2, v2) = iter.next().unwrap();
3336        claim_eq!(*k2, 1);
3337        claim_eq!(*v2, 12);
3338        let (k3, v3) = iter.next().unwrap();
3339        claim_eq!(*k3, 2);
3340        claim_eq!(*v3, 13);
3341        claim!(iter.next().is_none());
3342    }
3343
3344    #[concordium_test]
3345    fn iter_mut_works_on_nested_statemaps() {
3346        let mut state_builder = StateBuilder::open(StateApi::open());
3347        let mut outer_map = state_builder.new_map();
3348        let mut inner_map = state_builder.new_map();
3349        let _ = inner_map.insert(0u8, 1u8);
3350        let _ = inner_map.insert(1u8, 2u8);
3351        let _ = outer_map.insert(99u8, inner_map);
3352        for (_, mut v_map) in outer_map.iter_mut() {
3353            v_map.update(|v_map| {
3354                for (_, mut inner_v) in v_map.iter_mut() {
3355                    inner_v.update(|inner_v| *inner_v += 10);
3356                }
3357            });
3358        }
3359
3360        // Check the outer map.
3361        let mut outer_iter = outer_map.iter();
3362        let (inner_map_key, inner_map) = outer_iter.next().unwrap();
3363        claim_eq!(*inner_map_key, 99);
3364        claim!(outer_iter.next().is_none());
3365
3366        // Check the inner map.
3367        let mut inner_iter = inner_map.iter();
3368        let (k1, v1) = inner_iter.next().unwrap();
3369        claim_eq!(*k1, 0);
3370        claim_eq!(*v1, 11);
3371        let (k2, v2) = inner_iter.next().unwrap();
3372        claim_eq!(*k2, 1);
3373        claim_eq!(*v2, 12);
3374        claim!(inner_iter.next().is_none());
3375    }
3376
3377    #[concordium_test]
3378    fn statemap_iterator_unlocks_tree_once_dropped() {
3379        let mut state_builder = StateBuilder::open(StateApi::open());
3380        let mut map = state_builder.new_map();
3381        let _ = map.insert(0u8, 1u8);
3382        let _ = map.insert(1u8, 2u8);
3383        {
3384            let _iter = map.iter();
3385            // Uncommenting these two lines (and making iter mutable) should
3386            // give a compile error:
3387            //
3388            // map.insert(2u8, 3u8);
3389            // let n = iter.next();
3390        } // iter is dropped here, unlocking the subtree.
3391        let _ = map.insert(2u8, 3u8);
3392    }
3393
3394    #[concordium_test]
3395    fn high_level_stateset() {
3396        let my_set_key = "my_set";
3397        let mut state_builder = StateBuilder::open(StateApi::open());
3398
3399        let mut set = state_builder.new_set::<u8>();
3400        claim!(set.insert(0));
3401        claim!(set.insert(1));
3402        claim!(!set.insert(1));
3403        claim!(set.insert(2));
3404        claim!(set.remove(&2));
3405        state_builder.insert(my_set_key, set).expect("Insert failed");
3406
3407        claim!(state_builder.get::<_, StateSet<u8, _>>(my_set_key).unwrap().unwrap().contains(&0),);
3408        claim!(!state_builder.get::<_, StateSet<u8, _>>(my_set_key).unwrap().unwrap().contains(&2),);
3409
3410        let set = state_builder.get::<_, StateSet<u8, _>>(my_set_key).unwrap().unwrap();
3411        let mut iter = set.iter();
3412        claim_eq!(*iter.next().unwrap(), 0);
3413        claim_eq!(*iter.next().unwrap(), 1);
3414        claim!(iter.next().is_none());
3415    }
3416
3417    #[concordium_test]
3418    fn high_level_nested_stateset() {
3419        let inner_set_key = 0u8;
3420        let value = 255u8;
3421        let mut state_builder = StateBuilder::open(StateApi::open());
3422        let mut outer_map = state_builder.new_map::<u8, StateSet<u8, _>>();
3423        let mut inner_set = state_builder.new_set::<u8>();
3424
3425        inner_set.insert(value);
3426        let _ = outer_map.insert(inner_set_key, inner_set);
3427
3428        claim!(outer_map.get(&inner_set_key).unwrap().contains(&value));
3429    }
3430
3431    #[concordium_test]
3432    fn stateset_insert_remove() {
3433        let mut state_builder = StateBuilder::open(StateApi::open());
3434        let mut set = state_builder.new_set();
3435        let _ = set.insert(42);
3436        claim!(set.contains(&42));
3437        set.remove(&42);
3438        claim!(!set.contains(&42));
3439    }
3440
3441    #[concordium_test]
3442    fn stateset_clear() {
3443        let mut state_builder = StateBuilder::open(StateApi::open());
3444        let mut set = state_builder.new_set();
3445        let _ = set.insert(1);
3446        let _ = set.insert(2);
3447        let _ = set.insert(3);
3448        set.clear();
3449        claim!(set.is_empty());
3450    }
3451
3452    #[concordium_test]
3453    fn stateset_iterator_unlocks_tree_once_dropped() {
3454        let mut state_builder = StateBuilder::open(StateApi::open());
3455        let mut set = state_builder.new_set();
3456        set.insert(0u8);
3457        set.insert(1);
3458        {
3459            let _iter = set.iter();
3460            // Uncommenting these two lines (and making iter mutable) should
3461            // give a compile error:
3462            //
3463            // set.insert(2);
3464            // let n = iter.next();
3465        } // iter is dropped here, unlocking the subtree.
3466        set.insert(2);
3467    }
3468
3469    #[concordium_test]
3470    fn allocate_and_get_statebox() {
3471        let mut state_builder = StateBuilder::open(StateApi::open());
3472        let boxed_value = String::from("I'm boxed");
3473        let statebox = state_builder.new_box(boxed_value.clone());
3474        claim_eq!(*statebox.get(), boxed_value);
3475    }
3476
3477    #[concordium_test]
3478    fn a_new_entry_can_not_be_created_under_a_locked_subtree() {
3479        let expected_value: u64 = 123123123;
3480        let key = to_bytes(b"ab");
3481        let sub_key = to_bytes(b"abc");
3482        let mut state = StateApi::open();
3483        state
3484            .entry(&key[..])
3485            .or_insert_raw(&to_bytes(&expected_value))
3486            .expect("No iterators, so insertion should work.");
3487        claim!(state.iterator(&key).is_ok(), "Iterator should be present");
3488        let entry = state.create_entry(&sub_key);
3489        claim!(entry.is_err(), "Should not be able to create an entry under a locked subtree");
3490    }
3491
3492    #[concordium_test]
3493    fn a_new_entry_can_be_created_under_a_different_subtree_in_same_super_tree() {
3494        let expected_value: u64 = 123123123;
3495        let key = to_bytes(b"abcd");
3496        let key2 = to_bytes(b"abe");
3497        let mut state = StateApi::open();
3498        state
3499            .entry(&key[..])
3500            .or_insert_raw(&to_bytes(&expected_value))
3501            .expect("No iterators, so insertion should work.");
3502        claim!(state.iterator(&key).is_ok(), "Iterator should be present");
3503        let entry = state.create_entry(&key2);
3504        claim!(entry.is_ok(), "Failed to create a new entry under a different subtree");
3505    }
3506
3507    #[concordium_test]
3508    fn an_existing_entry_can_not_be_deleted_under_a_locked_subtree() {
3509        let expected_value: u64 = 123123123;
3510        let key = to_bytes(b"ab");
3511        let sub_key = to_bytes(b"abc");
3512        let mut state = StateApi::open();
3513        state
3514            .entry(&key[..])
3515            .or_insert_raw(&to_bytes(&expected_value))
3516            .expect("no iterators, so insertion should work.");
3517        let sub_entry = state
3518            .entry(sub_key)
3519            .or_insert_raw(&to_bytes(&expected_value))
3520            .expect("Should be possible to create the entry.");
3521        claim!(state.iterator(&key).is_ok(), "Iterator should be present");
3522        claim!(
3523            state.delete_entry(sub_entry).is_err(),
3524            "Should not be able to delete entry under a locked subtree"
3525        );
3526    }
3527
3528    #[concordium_test]
3529    fn an_existing_entry_can_be_deleted_from_a_different_subtree_in_same_super_tree() {
3530        let expected_value: u64 = 123123123;
3531        let key = to_bytes(b"abcd");
3532        let key2 = to_bytes(b"abe");
3533        let mut state = StateApi::open();
3534        state
3535            .entry(&key[..])
3536            .or_insert_raw(&to_bytes(&expected_value))
3537            .expect("No iterators, so insertion should work.");
3538        let entry2 = state
3539            .entry(key2)
3540            .or_insert_raw(&to_bytes(&expected_value))
3541            .expect("Should be possible to create the entry.");
3542        claim!(state.iterator(&key).is_ok(), "Iterator should be present");
3543        claim!(
3544            state.delete_entry(entry2).is_ok(),
3545            "Should be able to delete entry under a different subtree"
3546        );
3547    }
3548
3549    #[concordium_test]
3550    fn deleting_nested_stateboxes_works() {
3551        let mut state_builder = StateBuilder::open(StateApi::open());
3552        let inner_box = state_builder.new_box(99u8);
3553        let middle_box = state_builder.new_box(inner_box);
3554        let outer_box = state_builder.new_box(middle_box);
3555        outer_box.delete();
3556        let mut iter = state_builder.state_api.iterator(&[]).expect("Could not get iterator");
3557        // The only remaining node should be the state_builder's next_item_prefix node.
3558        claim!(iter.nth(1).is_none());
3559    }
3560
3561    #[concordium_test]
3562    fn clearing_statemap_with_stateboxes_works() {
3563        let mut state_builder = StateBuilder::open(StateApi::open());
3564        let box1 = state_builder.new_box(1u8);
3565        let box2 = state_builder.new_box(2u8);
3566        let box3 = state_builder.new_box(3u8);
3567        let mut map = state_builder.new_map();
3568        let _ = map.insert(1u8, box1);
3569        let _ = map.insert(2u8, box2);
3570        let _ = map.insert(3u8, box3);
3571        map.clear();
3572        let mut iter = state_builder.state_api.iterator(&[]).expect("Could not get iterator");
3573        // The only remaining node should be the state_builder's next_item_prefix node.
3574        claim!(iter.nth(1).is_none());
3575    }
3576
3577    #[concordium_test]
3578    fn clearing_nested_statemaps_works() {
3579        let mut state_builder = StateBuilder::open(StateApi::open());
3580        let mut inner_map_1 = state_builder.new_map();
3581        let _ = inner_map_1.insert(1u8, 2u8);
3582        let _ = inner_map_1.insert(2u8, 3u8);
3583        let _ = inner_map_1.insert(3u8, 4u8);
3584        let mut inner_map_2 = state_builder.new_map();
3585        let _ = inner_map_2.insert(11u8, 12u8);
3586        let _ = inner_map_2.insert(12u8, 13u8);
3587        let _ = inner_map_2.insert(13u8, 14u8);
3588        let mut outer_map = state_builder.new_map();
3589        let _ = outer_map.insert(0u8, inner_map_1);
3590        let _ = outer_map.insert(1u8, inner_map_2);
3591        outer_map.clear();
3592        let mut iter = state_builder.state_api.iterator(&[]).expect("Could not get iterator");
3593        // The only remaining node should be the state_builder's next_item_prefix node.
3594        claim!(iter.nth(1).is_none());
3595    }
3596
3597    #[concordium_test]
3598    fn occupied_entry_truncates_leftover_data() {
3599        let mut state_builder = StateBuilder::open(StateApi::open());
3600        let mut map = state_builder.new_map();
3601        let _ = map.insert(99u8, "A longer string that should be truncated".into());
3602        let a_short_string = "A short string".to_string();
3603        let expected_size = a_short_string.len() + 4; // 4 bytes for the length of the string.
3604        map.entry(99u8).and_modify(|v| *v = a_short_string);
3605        let actual_size = state_builder
3606            .state_api
3607            .lookup_entry(&[INITIAL_NEXT_ITEM_PREFIX[0], 0, 0, 0, 0, 0, 0, 0, 99])
3608            .expect("Lookup failed")
3609            .size()
3610            .expect("Getting size failed");
3611        claim_eq!(expected_size as u32, actual_size);
3612    }
3613
3614    #[concordium_test]
3615    fn occupied_entry_raw_truncates_leftover_data() {
3616        let mut state = StateApi::open();
3617        state
3618            .entry([])
3619            .or_insert_raw(&to_bytes(&"A longer string that should be truncated"))
3620            .expect("No iterators, so insertion should work.");
3621
3622        let a_short_string = "A short string";
3623        let expected_size = a_short_string.len() + 4; // 4 bytes for the length of the string.
3624
3625        match state.entry([]) {
3626            EntryRaw::Vacant(_) => panic!("Entry is vacant"),
3627            EntryRaw::Occupied(mut occ) => occ.insert_raw(&to_bytes(&a_short_string)),
3628        }
3629        let actual_size =
3630            state.lookup_entry(&[]).expect("Lookup failed").size().expect("Getting size failed");
3631        claim_eq!(expected_size as u32, actual_size);
3632    }
3633}