1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/// Executes a block of code unconstrained by the VM. This macro is useful for running code that
/// helps provide information to the program but does not need to be constrained by the VM. For
/// example, running `ecrecover` is expensive in the VM but verifying a signature when you know the
/// public key is not. `unconstrained` can be used to provide the public key without spending VM CPU
/// cycles.
///
/// Any changes to the VM state will be reset at the end of the block. To provide data to the VM,
/// use `io::hint` or `io::hint_slice`, and read it using `io::read` or `io::read_vec`.
#[macro_export]
macro_rules! unconstrained {
    (  $($block:tt)* ) => {
        use $crate::{syscall_enter_unconstrained, syscall_exit_unconstrained};

        let continue_unconstrained: bool;
        unsafe {
            continue_unconstrained = syscall_enter_unconstrained();
        }

        // If continue_unconstrained is true (only possible in the runtime), execute
        // the inner code. Otherwise, nothing happens.
        if continue_unconstrained {
            // Declare an immutable closure to ensure at compile time that no memory is changed
            let _unconstrained_closure = || -> () {
                $($block)*
            };

            _unconstrained_closure();

            unsafe {
                syscall_exit_unconstrained();
            }
        }

    };
}