[Feature] Support ChaCha::rand_* (#2433)

* Add tests for ChaCha::rand*

* Add Chacha::rand* to AST, tyc, and codegen

* Add lottery example

* Regen expectations

* Add check asserting that command is only used in finalize block

* Update example and related CI
This commit is contained in:
d0cd 2023-06-29 00:02:50 -04:00 committed by GitHub
parent c373b898c4
commit b236918df4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 465 additions and 1 deletions

View File

@ -341,3 +341,10 @@ if [ $EXITCODE -ne 0 ]; then
echo "The \`vote\` program failed to run successfully."
exit $EXITCODE
fi
# Build the lottery example Leo program.
echo "Building the \`lottery\` program..."
(
cd $EXAMPLES/lottery || exit
$LEO build || exit
)

View File

@ -91,6 +91,22 @@ pub enum CoreFunction {
BHP1024HashToU128,
BHP1024HashToScalar,
ChaChaRandAddress,
ChaChaRandBool,
ChaChaRandField,
ChaChaRandGroup,
ChaChaRandI8,
ChaChaRandI16,
ChaChaRandI32,
ChaChaRandI64,
ChaChaRandI128,
ChaChaRandU8,
ChaChaRandU16,
ChaChaRandU32,
ChaChaRandU64,
ChaChaRandU128,
ChaChaRandScalar,
Pedersen64CommitToAddress,
Pedersen64CommitToField,
Pedersen64CommitToGroup,
@ -257,6 +273,22 @@ impl CoreFunction {
(sym::BHP1024, sym::hash_to_u128) => Self::BHP1024HashToU128,
(sym::BHP1024, sym::hash_to_scalar) => Self::BHP1024HashToScalar,
(sym::ChaCha, sym::rand_address) => Self::ChaChaRandAddress,
(sym::ChaCha, sym::rand_bool) => Self::ChaChaRandBool,
(sym::ChaCha, sym::rand_field) => Self::ChaChaRandField,
(sym::ChaCha, sym::rand_group) => Self::ChaChaRandGroup,
(sym::ChaCha, sym::rand_i8) => Self::ChaChaRandI8,
(sym::ChaCha, sym::rand_i16) => Self::ChaChaRandI16,
(sym::ChaCha, sym::rand_i32) => Self::ChaChaRandI32,
(sym::ChaCha, sym::rand_i64) => Self::ChaChaRandI64,
(sym::ChaCha, sym::rand_i128) => Self::ChaChaRandI128,
(sym::ChaCha, sym::rand_scalar) => Self::ChaChaRandScalar,
(sym::ChaCha, sym::rand_u8) => Self::ChaChaRandU8,
(sym::ChaCha, sym::rand_u16) => Self::ChaChaRandU16,
(sym::ChaCha, sym::rand_u32) => Self::ChaChaRandU32,
(sym::ChaCha, sym::rand_u64) => Self::ChaChaRandU64,
(sym::ChaCha, sym::rand_u128) => Self::ChaChaRandU128,
(sym::Pedersen64, sym::commit_to_address) => Self::Pedersen64CommitToAddress,
(sym::Pedersen64, sym::commit_to_field) => Self::Pedersen64CommitToField,
(sym::Pedersen64, sym::commit_to_group) => Self::Pedersen64CommitToGroup,
@ -424,6 +456,22 @@ impl CoreFunction {
Self::BHP1024HashToU128 => 1,
Self::BHP1024HashToScalar => 1,
Self::ChaChaRandAddress => 0,
Self::ChaChaRandBool => 0,
Self::ChaChaRandField => 0,
Self::ChaChaRandGroup => 0,
Self::ChaChaRandI8 => 0,
Self::ChaChaRandI16 => 0,
Self::ChaChaRandI32 => 0,
Self::ChaChaRandI64 => 0,
Self::ChaChaRandI128 => 0,
Self::ChaChaRandU8 => 0,
Self::ChaChaRandU16 => 0,
Self::ChaChaRandU32 => 0,
Self::ChaChaRandU64 => 0,
Self::ChaChaRandU128 => 0,
Self::ChaChaRandScalar => 0,
Self::Pedersen64CommitToAddress => 2,
Self::Pedersen64CommitToField => 2,
Self::Pedersen64CommitToGroup => 2,
@ -513,4 +561,174 @@ impl CoreFunction {
Self::GroupToYCoordinate => 1,
}
}
/// Returns whether or not this function is finalize command.
pub fn is_finalize_command(&self) -> bool {
match self {
CoreFunction::ChaChaRandAddress
| CoreFunction::ChaChaRandBool
| CoreFunction::ChaChaRandField
| CoreFunction::ChaChaRandGroup
| CoreFunction::ChaChaRandI8
| CoreFunction::ChaChaRandI16
| CoreFunction::ChaChaRandI32
| CoreFunction::ChaChaRandI64
| CoreFunction::ChaChaRandI128
| CoreFunction::ChaChaRandU8
| CoreFunction::ChaChaRandU16
| CoreFunction::ChaChaRandU32
| CoreFunction::ChaChaRandU64
| CoreFunction::ChaChaRandU128
| CoreFunction::MappingGet
| CoreFunction::MappingGetOrUse
| CoreFunction::ChaChaRandScalar
| CoreFunction::MappingSet => true,
CoreFunction::BHP256CommitToAddress
| CoreFunction::BHP256CommitToField
| CoreFunction::BHP256CommitToGroup
| CoreFunction::BHP256HashToAddress
| CoreFunction::BHP256HashToField
| CoreFunction::BHP256HashToGroup
| CoreFunction::BHP256HashToI8
| CoreFunction::BHP256HashToI16
| CoreFunction::BHP256HashToI32
| CoreFunction::BHP256HashToI64
| CoreFunction::BHP256HashToI128
| CoreFunction::BHP256HashToU8
| CoreFunction::BHP256HashToU16
| CoreFunction::BHP256HashToU32
| CoreFunction::BHP256HashToU64
| CoreFunction::BHP256HashToU128
| CoreFunction::BHP256HashToScalar
| CoreFunction::BHP512CommitToAddress
| CoreFunction::BHP512CommitToField
| CoreFunction::BHP512CommitToGroup
| CoreFunction::BHP512HashToAddress
| CoreFunction::BHP512HashToField
| CoreFunction::BHP512HashToGroup
| CoreFunction::BHP512HashToI8
| CoreFunction::BHP512HashToI16
| CoreFunction::BHP512HashToI32
| CoreFunction::BHP512HashToI64
| CoreFunction::BHP512HashToI128
| CoreFunction::BHP512HashToU8
| CoreFunction::BHP512HashToU16
| CoreFunction::BHP512HashToU32
| CoreFunction::BHP512HashToU64
| CoreFunction::BHP512HashToU128
| CoreFunction::BHP512HashToScalar
| CoreFunction::BHP768CommitToAddress
| CoreFunction::BHP768CommitToField
| CoreFunction::BHP768CommitToGroup
| CoreFunction::BHP768HashToAddress
| CoreFunction::BHP768HashToField
| CoreFunction::BHP768HashToGroup
| CoreFunction::BHP768HashToI8
| CoreFunction::BHP768HashToI16
| CoreFunction::BHP768HashToI32
| CoreFunction::BHP768HashToI64
| CoreFunction::BHP768HashToI128
| CoreFunction::BHP768HashToU8
| CoreFunction::BHP768HashToU16
| CoreFunction::BHP768HashToU32
| CoreFunction::BHP768HashToU64
| CoreFunction::BHP768HashToU128
| CoreFunction::BHP768HashToScalar
| CoreFunction::BHP1024CommitToAddress
| CoreFunction::BHP1024CommitToField
| CoreFunction::BHP1024CommitToGroup
| CoreFunction::BHP1024HashToAddress
| CoreFunction::BHP1024HashToField
| CoreFunction::BHP1024HashToGroup
| CoreFunction::BHP1024HashToI8
| CoreFunction::BHP1024HashToI16
| CoreFunction::BHP1024HashToI32
| CoreFunction::BHP1024HashToI64
| CoreFunction::BHP1024HashToI128
| CoreFunction::BHP1024HashToU8
| CoreFunction::BHP1024HashToU16
| CoreFunction::BHP1024HashToU32
| CoreFunction::BHP1024HashToU64
| CoreFunction::BHP1024HashToU128
| CoreFunction::BHP1024HashToScalar
| CoreFunction::Pedersen64CommitToAddress
| CoreFunction::Pedersen64CommitToField
| CoreFunction::Pedersen64CommitToGroup
| CoreFunction::Pedersen64HashToAddress
| CoreFunction::Pedersen64HashToField
| CoreFunction::Pedersen64HashToGroup
| CoreFunction::Pedersen64HashToI8
| CoreFunction::Pedersen64HashToI16
| CoreFunction::Pedersen64HashToI32
| CoreFunction::Pedersen64HashToI64
| CoreFunction::Pedersen64HashToI128
| CoreFunction::Pedersen64HashToU8
| CoreFunction::Pedersen64HashToU16
| CoreFunction::Pedersen64HashToU32
| CoreFunction::Pedersen64HashToU64
| CoreFunction::Pedersen64HashToU128
| CoreFunction::Pedersen64HashToScalar
| CoreFunction::Pedersen128CommitToAddress
| CoreFunction::Pedersen128CommitToField
| CoreFunction::Pedersen128CommitToGroup
| CoreFunction::Pedersen128HashToAddress
| CoreFunction::Pedersen128HashToField
| CoreFunction::Pedersen128HashToGroup
| CoreFunction::Pedersen128HashToI8
| CoreFunction::Pedersen128HashToI16
| CoreFunction::Pedersen128HashToI32
| CoreFunction::Pedersen128HashToI64
| CoreFunction::Pedersen128HashToI128
| CoreFunction::Pedersen128HashToU8
| CoreFunction::Pedersen128HashToU16
| CoreFunction::Pedersen128HashToU32
| CoreFunction::Pedersen128HashToU64
| CoreFunction::Pedersen128HashToU128
| CoreFunction::Pedersen128HashToScalar
| CoreFunction::Poseidon2HashToAddress
| CoreFunction::Poseidon2HashToField
| CoreFunction::Poseidon2HashToGroup
| CoreFunction::Poseidon2HashToI8
| CoreFunction::Poseidon2HashToI16
| CoreFunction::Poseidon2HashToI32
| CoreFunction::Poseidon2HashToI64
| CoreFunction::Poseidon2HashToI128
| CoreFunction::Poseidon2HashToU8
| CoreFunction::Poseidon2HashToU16
| CoreFunction::Poseidon2HashToU32
| CoreFunction::Poseidon2HashToU64
| CoreFunction::Poseidon2HashToU128
| CoreFunction::Poseidon2HashToScalar
| CoreFunction::Poseidon4HashToAddress
| CoreFunction::Poseidon4HashToField
| CoreFunction::Poseidon4HashToGroup
| CoreFunction::Poseidon4HashToI8
| CoreFunction::Poseidon4HashToI16
| CoreFunction::Poseidon4HashToI32
| CoreFunction::Poseidon4HashToI64
| CoreFunction::Poseidon4HashToI128
| CoreFunction::Poseidon4HashToU8
| CoreFunction::Poseidon4HashToU16
| CoreFunction::Poseidon4HashToU32
| CoreFunction::Poseidon4HashToU64
| CoreFunction::Poseidon4HashToU128
| CoreFunction::Poseidon4HashToScalar
| CoreFunction::Poseidon8HashToAddress
| CoreFunction::Poseidon8HashToField
| CoreFunction::Poseidon8HashToGroup
| CoreFunction::Poseidon8HashToI8
| CoreFunction::Poseidon8HashToI16
| CoreFunction::Poseidon8HashToI32
| CoreFunction::Poseidon8HashToI64
| CoreFunction::Poseidon8HashToI128
| CoreFunction::Poseidon8HashToU8
| CoreFunction::Poseidon8HashToU16
| CoreFunction::Poseidon8HashToU32
| CoreFunction::Poseidon8HashToU64
| CoreFunction::Poseidon8HashToU128
| CoreFunction::Poseidon8HashToScalar
| CoreFunction::GroupToXCoordinate
| CoreFunction::GroupToYCoordinate => false,
}
}
}

View File

@ -381,6 +381,33 @@ impl<'a> CodeGenerator<'a> {
_ => unreachable!("The only associated methods of group are to_x_coordinate and to_y_coordinate"),
}
}
Type::Identifier(Identifier { name: sym::ChaCha, .. }) => {
// Get the destination register.
let destination_register = get_destination_register();
// Construct the instruction template.
let mut instruction = format!(" rand.chacha into {destination_register} as ");
// Write the return type.
match input.name {
Identifier { name: sym::rand_address, .. } => writeln!(instruction, "address;"),
Identifier { name: sym::rand_bool, .. } => writeln!(instruction, "boolean;"),
Identifier { name: sym::rand_field, .. } => writeln!(instruction, "field;"),
Identifier { name: sym::rand_group, .. } => writeln!(instruction, "group;"),
Identifier { name: sym::rand_i8, .. } => writeln!(instruction, "i8;"),
Identifier { name: sym::rand_i16, .. } => writeln!(instruction, "i16;"),
Identifier { name: sym::rand_i32, .. } => writeln!(instruction, "i32;"),
Identifier { name: sym::rand_i64, .. } => writeln!(instruction, "i64;"),
Identifier { name: sym::rand_i128, .. } => writeln!(instruction, "i128;"),
Identifier { name: sym::rand_scalar, .. } => writeln!(instruction, "scalar;"),
Identifier { name: sym::rand_u8, .. } => writeln!(instruction, "u8;"),
Identifier { name: sym::rand_u16, .. } => writeln!(instruction, "u16;"),
Identifier { name: sym::rand_u32, .. } => writeln!(instruction, "u32;"),
Identifier { name: sym::rand_u64, .. } => writeln!(instruction, "u64;"),
Identifier { name: sym::rand_u128, .. } => writeln!(instruction, "u128;"),
_ => unreachable!("The only associated methods of ChaCha are `rand_*`"),
}
.expect("failed to write to string");
(destination_register, instruction)
}
_ => unreachable!("All core functions should be known at this phase of compilation"),
};
// Add the instruction to the list of instructions.

View File

@ -45,6 +45,11 @@ impl<'a> ExpressionVisitor<'a> for TypeChecker<'a> {
AccessExpression::AssociatedFunction(access) => {
// Check core struct name and function.
if let Some(core_instruction) = self.get_core_function_call(&access.ty, &access.name) {
// Check that operation is not restricted to finalize blocks.
if !self.is_finalize && core_instruction.is_finalize_command() {
self.emit_err(TypeCheckerError::operation_must_be_in_finalize_block(input.span()));
}
// Get the types of the arguments.
let argument_types = access
.arguments
@ -59,6 +64,7 @@ impl<'a> ExpressionVisitor<'a> for TypeChecker<'a> {
if let Some(expected) = expected {
self.assert_type(&return_type, expected, input.span());
}
return return_type;
} else {
self.emit_err(TypeCheckerError::invalid_core_function_call(access, access.span()));

View File

@ -866,6 +866,21 @@ impl<'a> TypeChecker<'a> {
self.assert_group_type(&arguments[0].0, arguments[0].1);
Some(Type::Field)
}
CoreFunction::ChaChaRandAddress => Some(Type::Address),
CoreFunction::ChaChaRandBool => Some(Type::Boolean),
CoreFunction::ChaChaRandField => Some(Type::Field),
CoreFunction::ChaChaRandGroup => Some(Type::Group),
CoreFunction::ChaChaRandI8 => Some(Type::Integer(IntegerType::I8)),
CoreFunction::ChaChaRandI16 => Some(Type::Integer(IntegerType::I16)),
CoreFunction::ChaChaRandI32 => Some(Type::Integer(IntegerType::I32)),
CoreFunction::ChaChaRandI64 => Some(Type::Integer(IntegerType::I64)),
CoreFunction::ChaChaRandI128 => Some(Type::Integer(IntegerType::I128)),
CoreFunction::ChaChaRandScalar => Some(Type::Scalar),
CoreFunction::ChaChaRandU8 => Some(Type::Integer(IntegerType::U8)),
CoreFunction::ChaChaRandU16 => Some(Type::Integer(IntegerType::U16)),
CoreFunction::ChaChaRandU32 => Some(Type::Integer(IntegerType::U32)),
CoreFunction::ChaChaRandU64 => Some(Type::Integer(IntegerType::U64)),
CoreFunction::ChaChaRandU128 => Some(Type::Integer(IntegerType::U128)),
}
}

View File

@ -149,6 +149,7 @@ symbols! {
BHP512,
BHP768,
BHP1024,
ChaCha,
commit_to_address,
commit_to_field,
commit_to_group,
@ -174,6 +175,21 @@ symbols! {
Poseidon2,
Poseidon4,
Poseidon8,
rand_address,
rand_bool,
rand_field,
rand_group,
rand_i8,
rand_i16,
rand_i32,
rand_i64,
rand_i128,
rand_scalar,
rand_u8,
rand_u16,
rand_u32,
rand_u64,
rand_u128,
set,
to_x_coordinate,
to_y_coordinate,

View File

@ -635,4 +635,11 @@ create_messages!(
msg: format!("`{operation}` is not a valid operand in a finalize context."),
help: None,
}
@formatted
operation_must_be_in_finalize_block {
args: (),
msg: format!("This operation can only be used in a `finalize` block."),
help: None,
}
);

2
examples/lottery/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
outputs/
build/

View File

@ -0,0 +1,8 @@
# lottery.aleo
## Build Guide
To compile this Aleo program, run:
```bash
aleo build
```

View File

@ -0,0 +1,4 @@
// The program input for lottery/src/main.leo
[main]
public a: u32 = 1u32;
b: u32 = 2u32;

View File

@ -0,0 +1,10 @@
{
"program": "lottery.aleo",
"version": "0.0.0",
"description": "",
"development": {
"private_key": "APrivateKey1zkpJrHD9orEuTpL8dDnSBZo6VyKWdbrk3VJfcwEv9SsQBN2",
"address": "aleo1dvx603addv7c2uqj6ksm9hccaypzn0ngus4n2vygvdlhqvkcyyfqvh4zdz"
},
"license": "MIT"
}

View File

@ -0,0 +1,30 @@
// The 'lottery' program.
program lottery.aleo {
mapping num_winners: u8 => u8;
record Ticket {
owner: address,
}
transition play() -> Ticket {
let ticket: Ticket = Ticket {
owner: self.caller,
};
return ticket then finalize();
}
finalize play() {
// Check that the lottery has not expired.
assert(block.height <= 1000u32);
// Randomly select whether or not the ticket is a winner.
assert(ChaCha::rand_bool());
// Check that the maximum number of winners have not been reached.
let winners: u8 = num_winners.get_or_use(0u8, 0u8);
assert(winners < 5u8);
num_winners.set(0u8, winners + 1u8);
}
}

View File

@ -2,4 +2,4 @@
namespace: Compile
expectation: Fail
outputs:
- "Error [ETYC0372035]: `Mapping::set` must be inside a finalize block.\n --> compiler-test:8:9\n |\n 8 | Mapping::set(values, 0u8, 1u8);\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nError [ETYC0372035]: `Mapping::get_or` must be inside a finalize block.\n --> compiler-test:9:9\n |\n 9 | Mapping::get_or_use(account, self.caller, 1u64);\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nError [ETYC0372035]: `Mapping::get` must be inside a finalize block.\n --> compiler-test:10:9\n |\n 10 | Mapping::get(values, 1u8);\n | ^^^^^^^^^^^^^^^^^^^^^^^^^\nError [ETYC0372035]: `Mapping::set` must be inside a finalize block.\n --> compiler-test:14:9\n |\n 14 | Mapping::set(values, 0u8, 1u8);\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nError [ETYC0372035]: `Mapping::get_or` must be inside a finalize block.\n --> compiler-test:15:9\n |\n 15 | Mapping::get_or_use(account, self.caller, 1u64);\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nError [ETYC0372035]: `Mapping::get` must be inside a finalize block.\n --> compiler-test:16:9\n |\n 16 | Mapping::get(values, 0u8);\n | ^^^^^^^^^^^^^^^^^^^^^^^^^\nError [ETYC0372044]: Function must contain a `finalize` statement on all execution paths.\n --> compiler-test:13:5\n |\n 13 | inline bar() {\n 14 | Mapping::set(values, 0u8, 1u8);\n 15 | Mapping::get_or_use(account, self.caller, 1u64);\n 16 | Mapping::get(values, 0u8);\n 17 | }\n | ^\nError [ETYC0372031]: Only transition functions can have a `finalize` block.\n --> compiler-test:19:5\n |\n 19 | finalize finalize_no_params() {\n 20 | foo();\n 21 | bar();\n 22 | }\n | ^\n |\n = Remove the `finalize` block or use the keyword `transition` instead of `function`.\nError [ETYC0372045]: `finalize` name `bar` does not match function name `finalize_no_params`\n --> compiler-test:19:5\n |\n 19 | finalize finalize_no_params() {\n 20 | foo();\n 21 | bar();\n 22 | }\n | ^\nError [ETYC0372066]: Cyclic dependency between functions: `bar` --> `bar`\n"
- "Error [ETYC0372077]: This operation can only be used in a `finalize` block.\n --> compiler-test:8:9\n |\n 8 | Mapping::set(values, 0u8, 1u8);\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nError [ETYC0372035]: `Mapping::set` must be inside a finalize block.\n --> compiler-test:8:9\n |\n 8 | Mapping::set(values, 0u8, 1u8);\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nError [ETYC0372077]: This operation can only be used in a `finalize` block.\n --> compiler-test:9:9\n |\n 9 | Mapping::get_or_use(account, self.caller, 1u64);\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nError [ETYC0372035]: `Mapping::get_or` must be inside a finalize block.\n --> compiler-test:9:9\n |\n 9 | Mapping::get_or_use(account, self.caller, 1u64);\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nError [ETYC0372077]: This operation can only be used in a `finalize` block.\n --> compiler-test:10:9\n |\n 10 | Mapping::get(values, 1u8);\n | ^^^^^^^^^^^^^^^^^^^^^^^^^\nError [ETYC0372035]: `Mapping::get` must be inside a finalize block.\n --> compiler-test:10:9\n |\n 10 | Mapping::get(values, 1u8);\n | ^^^^^^^^^^^^^^^^^^^^^^^^^\nError [ETYC0372077]: This operation can only be used in a `finalize` block.\n --> compiler-test:14:9\n |\n 14 | Mapping::set(values, 0u8, 1u8);\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nError [ETYC0372035]: `Mapping::set` must be inside a finalize block.\n --> compiler-test:14:9\n |\n 14 | Mapping::set(values, 0u8, 1u8);\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nError [ETYC0372077]: This operation can only be used in a `finalize` block.\n --> compiler-test:15:9\n |\n 15 | Mapping::get_or_use(account, self.caller, 1u64);\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nError [ETYC0372035]: `Mapping::get_or` must be inside a finalize block.\n --> compiler-test:15:9\n |\n 15 | Mapping::get_or_use(account, self.caller, 1u64);\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nError [ETYC0372077]: This operation can only be used in a `finalize` block.\n --> compiler-test:16:9\n |\n 16 | Mapping::get(values, 0u8);\n | ^^^^^^^^^^^^^^^^^^^^^^^^^\nError [ETYC0372035]: `Mapping::get` must be inside a finalize block.\n --> compiler-test:16:9\n |\n 16 | Mapping::get(values, 0u8);\n | ^^^^^^^^^^^^^^^^^^^^^^^^^\nError [ETYC0372044]: Function must contain a `finalize` statement on all execution paths.\n --> compiler-test:13:5\n |\n 13 | inline bar() {\n 14 | Mapping::set(values, 0u8, 1u8);\n 15 | Mapping::get_or_use(account, self.caller, 1u64);\n 16 | Mapping::get(values, 0u8);\n 17 | }\n | ^\nError [ETYC0372031]: Only transition functions can have a `finalize` block.\n --> compiler-test:19:5\n |\n 19 | finalize finalize_no_params() {\n 20 | foo();\n 21 | bar();\n 22 | }\n | ^\n |\n = Remove the `finalize` block or use the keyword `transition` instead of `function`.\nError [ETYC0372045]: `finalize` name `bar` does not match function name `finalize_no_params`\n --> compiler-test:19:5\n |\n 19 | finalize finalize_no_params() {\n 20 | foo();\n 21 | bar();\n 22 | }\n | ^\nError [ETYC0372066]: Cyclic dependency between functions: `bar` --> `bar`\n"

View File

@ -0,0 +1,12 @@
---
namespace: Compile
expectation: Pass
outputs:
- - initial_ast: 2d7b208912c97c514488786ee171503bfe6d230fb6f0f35725fdcc0d217dad20
unrolled_ast: 2d7b208912c97c514488786ee171503bfe6d230fb6f0f35725fdcc0d217dad20
ssa_ast: d31261c1b1ffc59dae4f917070deae35adcb480707a00e4ce900458f962855cc
flattened_ast: 57633e91a7d54fa5f5ec007863b135a0b1bca23f3016c2bc01ab8293ad2f59d4
inlined_ast: 57633e91a7d54fa5f5ec007863b135a0b1bca23f3016c2bc01ab8293ad2f59d4
dce_ast: 09659efca22ece8c63c317e0e22e1400871541e2d40a6604e073e64a7fc54153
bytecode: 268f9afb6b8472b88b0c91f927b0cd4a69c10ad4457714dbb6faddeee5405cc6
warnings: ""

View File

@ -0,0 +1,5 @@
---
namespace: Compile
expectation: Fail
outputs:
- "Error [ETYC0372006]: Call expected `0` args, but got `1`\n --> compiler-test:12:24\n |\n 12 | let a: field = ChaCha::rand_field(1field);\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^\nError [ETYC0372006]: Call expected `0` args, but got `2`\n --> compiler-test:13:24\n |\n 13 | let b: field = ChaCha::rand_field(1field, 2field);\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"

View File

@ -0,0 +1,5 @@
---
namespace: Compile
expectation: Fail
outputs:
- "Error [ETYC0372007]: Expected one type from `scalar`, but got `field`\n --> compiler-test:12:25\n |\n 12 | let a: scalar = ChaCha::rand_field();\n | ^^^^^^^^^^^^^^^^^^^^\nError [ETYC0372007]: Expected one type from `group`, but got `field`\n --> compiler-test:13:24\n |\n 13 | let b: group = ChaCha::rand_field();\n | ^^^^^^^^^^^^^^^^^^^^\n"

View File

@ -0,0 +1,5 @@
---
namespace: Compile
expectation: Fail
outputs:
- "Error [ETYC0372077]: This operation can only be used in a `finalize` block.\n --> compiler-test:8:25\n |\n 8 | let a: scalar = ChaCha::rand_scalar();\n | ^^^^^^^^^^^^^^^^^^^^^\n"

View File

@ -0,0 +1,30 @@
/*
namespace: Compile
expectation: Pass
*/
program test.aleo {
transition foo() {
return then finalize();
}
finalize foo() {
let a: address = ChaCha::rand_address();
let b: bool = ChaCha::rand_bool();
let c: field = ChaCha::rand_field();
let d: group = ChaCha::rand_group();
let e: i8 = ChaCha::rand_i8();
let f: i16 = ChaCha::rand_i16();
let g: i32 = ChaCha::rand_i32();
let h: i64 = ChaCha::rand_i64();
let i: i128 = ChaCha::rand_i128();
let j: scalar = ChaCha::rand_scalar();
let k: u8 = ChaCha::rand_u8();
let l: u16 = ChaCha::rand_u16();
let m: u32 = ChaCha::rand_u32();
let n: u64 = ChaCha::rand_u64();
let o: u128 = ChaCha::rand_u128();
assert(b);
}
}

View File

@ -0,0 +1,19 @@
/*
namespace: Compile
expectation: Fail
*/
program test.aleo {
mapping values: field => field;
transition foo() {
return then finalize();
}
finalize foo() {
let a: field = ChaCha::rand_field(1field);
let b: field = ChaCha::rand_field(1field, 2field);
values.set(a, b);
}
}

View File

@ -0,0 +1,19 @@
/*
namespace: Compile
expectation: Fail
*/
program test.aleo {
mapping values: scalar => group;
transition foo() {
return then finalize();
}
finalize foo() {
let a: scalar = ChaCha::rand_field();
let b: group = ChaCha::rand_field();
values.set(a, b);
}
}

View File

@ -0,0 +1,19 @@
/*
namespace: Compile
expectation: Fail
*/
program test.aleo {
mapping values: scalar => group;
transition foo() {
let a: scalar = ChaCha::rand_scalar();
return then finalize(a);
}
finalize foo(a: scalar) {
let b: group = ChaCha::rand_group();
values.set(a, b);
}
}