mirror of
https://github.com/AleoHQ/leo.git
synced 2024-11-13 08:47:17 +03:00
[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:
parent
c373b898c4
commit
b236918df4
@ -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
|
||||
)
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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()));
|
||||
|
@ -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)),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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
2
examples/lottery/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
outputs/
|
||||
build/
|
8
examples/lottery/README.md
Normal file
8
examples/lottery/README.md
Normal file
@ -0,0 +1,8 @@
|
||||
# lottery.aleo
|
||||
|
||||
## Build Guide
|
||||
|
||||
To compile this Aleo program, run:
|
||||
```bash
|
||||
aleo build
|
||||
```
|
4
examples/lottery/inputs/lottery.in
Normal file
4
examples/lottery/inputs/lottery.in
Normal file
@ -0,0 +1,4 @@
|
||||
// The program input for lottery/src/main.leo
|
||||
[main]
|
||||
public a: u32 = 1u32;
|
||||
b: u32 = 2u32;
|
10
examples/lottery/program.json
Normal file
10
examples/lottery/program.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"program": "lottery.aleo",
|
||||
"version": "0.0.0",
|
||||
"description": "",
|
||||
"development": {
|
||||
"private_key": "APrivateKey1zkpJrHD9orEuTpL8dDnSBZo6VyKWdbrk3VJfcwEv9SsQBN2",
|
||||
"address": "aleo1dvx603addv7c2uqj6ksm9hccaypzn0ngus4n2vygvdlhqvkcyyfqvh4zdz"
|
||||
},
|
||||
"license": "MIT"
|
||||
}
|
30
examples/lottery/src/main.leo
Normal file
30
examples/lottery/src/main.leo
Normal 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);
|
||||
|
||||
}
|
||||
}
|
@ -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"
|
||||
|
12
tests/expectations/compiler/finalize/rand.out
Normal file
12
tests/expectations/compiler/finalize/rand.out
Normal 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: ""
|
@ -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"
|
@ -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"
|
@ -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"
|
30
tests/tests/compiler/finalize/rand.leo
Normal file
30
tests/tests/compiler/finalize/rand.leo
Normal 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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
19
tests/tests/compiler/finalize/rand_incorrect_type_fail.leo
Normal file
19
tests/tests/compiler/finalize/rand_incorrect_type_fail.leo
Normal 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);
|
||||
}
|
||||
}
|
19
tests/tests/compiler/finalize/rand_not_in_finalize.leo
Normal file
19
tests/tests/compiler/finalize/rand_not_in_finalize.leo
Normal 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);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user