Skip to content

v1.7.0

Compare
Choose a tag to compare
@github-actions github-actions released this 20 Apr 01:22
· 1049 commits to testnet3 since this release

Changes

New Syntax - Mapping and finalize

The syntax around mappings and finalize has been updated to support get, get_or_init, set functions.

program test.aleo {
    mapping counter: address => u64;

    transition dubble() {
        return then finalize(self.caller);
    }

    finalize dubble(addr: address) {
        let current_value: u64 = Mapping::get_or_init(counter, addr, 0u64);
        Mapping::set(counter, addr, current_value + 1u64);
        current_value = Mapping::get(counter, addr);
        Mapping::set(counter, addr, current_value + 1u64);
    }

}

Mapping

The mapping struct allows the programmer to apply updates to a program mapping data structure by calling one of the following functions.

get

A get command, e.g. current_value = Mapping::get(counter, addr);
Gets the value stored at addr in counter and stores the result in current_value
If the value at addr does not exist, then the program will fail to execute.

get_or_init

A get command that initializes the mapping in case of failure, e.g.
let current_value: u64 = Mapping::get_or_init(counter, addr, 0u64);
Gets the value stored at addr in counter and stores the result in current_value.
If the key is not present, 0u64 is stored in counter and stored in current_value.

set

A set command, e.g. Mapping::set(counter, addr, current_value + 1u64);
Sets the addr entry as current_value + 1u64 in counter.

Deprecated Syntax

increment

The increment function has been removed from Leo syntax.
Developers can increment values in a mapping using set

decrement

The decrement function has been removed from Leo syntax.
Developers can decrement values in a mapping using set

New Syntax - Inlined Functions

Users can specify inlined functions in the following way:

inline foo(a: u8, b: u8) -> u8 { ... }

With this new addition, the rules for functions (in the traditional sense) are as follows:

  • There are three variants of functions: transition, function, inline.
  • transitions can only call functions and inlines.
  • functions can only call inlines.
  • inlines can only call inlines.
  • Direct/indirect recursive calls are not allowed

New Optimization - Dead Code Elimination

Dead Code Elimination (DCE) - The Leo compiler will identify and remove unused code blocks in programs - simplifying the generated zk circuit and saving the programmer credits for every execution.
Lets look at DCE in action. Consider the following Leo program and its generated bytecode.

program test.aleo {
    record dummy {
        owner: address,
        gates: u64,
        data: u8,
   

    inline inline_and_eliminate(a: u8, b: u8) -> u8 {
        return a * b;
    }

    transition foo(a: u8, b: u8) -> u8 {
        let c: u8 = a + b;
        let d: u8 = 0u8;
        if (a == b) {
            d = inline_and_eliminate(a, b);
        }
        let e: dummy = dummy {
            owner: self.caller,
            gates: 0u64,
            data: d,
        };
        return a + b;
    }
}

Initial Leo program above.

program test.aleo;

record dummy:
    owner as address.private;
    gates as u64.private;
    data as u8.private;

function foo:
    input r0 as u8.private;
    input r1 as u8.private;
    add r0 r1 into r2;
    output r2 as u8.private;

Compiled bytecode above.

Observation One

Observe that the inline function inline_and_eliminate is not produced in the compiled bytecode. Under the hood, Leo substitutes the code directly from inline_and_eliminate into the transition function foo where it is used. After the code is substituted, the inline function can be removed from the program tree.

Observation Two

Observe that the variables d, e, and the Leo code computing their values are not produced in the compiled bytecode. Leo’s DCE optimization has been hard at work recognizing that the if conditional, the inline function and the record creation are not output by the transition function foo. The last line of the initial program return a + b is the only computation executed by foo. All other code is unnecessary computation in the program and marked as “dead”. Leo will remove the dead code from the program tree before the resulting bytecode is generated.

Bug fixes