diff --git a/.circleci/lottery/src/main.leo b/.circleci/lottery/src/main.leo index ebab61459e8..6b42061f649 100644 --- a/.circleci/lottery/src/main.leo +++ b/.circleci/lottery/src/main.leo @@ -11,7 +11,7 @@ program lottery.aleo { } fn play() -> (Ticket, Final) { - let ticket: Ticket = Ticket { owner: self.caller }; + let ticket: Ticket = Ticket { owner: std::ctx::caller() }; return ( ticket, final { @@ -23,7 +23,7 @@ program lottery.aleo { final fn finalize_play() { // Check that the lottery has not expired. - assert(block.height <= 1000u32); + assert(std::ctx::block_height() <= 1000u32); // Randomly select whether or not the ticket is a winner. assert(ChaCha::rand_bool()); diff --git a/.circleci/token/src/main.leo b/.circleci/token/src/main.leo index 90ab781ba63..04de2873668 100644 --- a/.circleci/token/src/main.leo +++ b/.circleci/token/src/main.leo @@ -28,7 +28,7 @@ program token.aleo { /* Transfer */ fn transfer_public(public receiver: address, public amount: u64) -> Final { // Transfer the tokens publicly, by invoking the computation on-chain. - return final { finalize_transfer_public(self.caller, receiver, amount); }; + return final { finalize_transfer_public(std::ctx::caller(), receiver, amount); }; } // The function `transfer_private` sends the specified token amount to the token receiver from the specified token record. @@ -80,7 +80,7 @@ program token.aleo { return ( transferred, final { - finalize_transfer_public_to_private(self.caller, amount); + finalize_transfer_public_to_private(std::ctx::caller(), amount); }, ); } diff --git a/crates/ast/src/functions/intrinsic.rs b/crates/ast/src/functions/intrinsic.rs index 5002954c24f..3280433dc01 100644 --- a/crates/ast/src/functions/intrinsic.rs +++ b/crates/ast/src/functions/intrinsic.rs @@ -1204,10 +1204,6 @@ impl Intrinsic { (sym::group, sym::to_x_coordinate) => sym::_group_to_x_coordinate, (sym::group, sym::to_y_coordinate) => sym::_group_to_y_coordinate, - (sym::ProgramCore, sym::checksum) => sym::_program_checksum, - (sym::ProgramCore, sym::edition) => sym::_program_edition, - (sym::ProgramCore, sym::program_owner) => sym::_program_owner, - (sym::ProgramCore, sym::function_checksum) => sym::_function_checksum, (sym::signature, sym::verify) => sym::_signature_verify, (sym::Final, sym::run) => sym::_final_run, diff --git a/crates/compiler/src/compiler.rs b/crates/compiler/src/compiler.rs index aab50b428b5..699f8c4e039 100644 --- a/crates/compiler/src/compiler.rs +++ b/crates/compiler/src/compiler.rs @@ -941,23 +941,34 @@ impl Compiler { /// Registers the implicit `std` library on `self.import_stubs`. /// - /// Reuses an existing entry if one was preloaded + /// Reuses an existing entry if one was preloaded. fn inject_std_library(&mut self) -> Result<()> { if self.compiler_options.no_std { return Ok(()); } let std_name = Symbol::intern(leo_std::library_name()); - let parent = Symbol::intern(self.unit_name.as_deref().expect("Cannot get unit name")); + let unit_parent = Symbol::intern(self.unit_name.as_deref().expect("Cannot get unit name")); + + let mut parents: Vec = self + .import_stubs + .iter() + .filter_map(|(name, _)| if *name == std_name { None } else { Some(*name) }) + .collect(); + parents.push(unit_parent); if let Some(existing) = self.import_stubs.get_mut(&std_name) { - existing.add_parent(parent); + for parent in parents { + existing.add_parent(parent); + } return Ok(()); } let mut stub = Self::build_std_stub(self.state.handler.clone(), Rc::clone(&self.state.node_builder), self.state.network)?; - stub.add_parent(parent); + for parent in parents { + stub.add_parent(parent); + } self.import_stubs.insert(std_name, stub); Ok(()) } @@ -1485,7 +1496,7 @@ mod tests { " @noupgrade\n", " constructor() {}\n", " fn foo() -> R {\n", - " return R { owner: self.signer, x: true };\n", + " return R { owner: std::ctx::signer(), x: true };\n", " }\n", "}\n", ); diff --git a/crates/fmt/tests/harness.rs b/crates/fmt/tests/harness.rs index c663db9b4de..9169ffb8499 100644 --- a/crates/fmt/tests/harness.rs +++ b/crates/fmt/tests/harness.rs @@ -401,6 +401,7 @@ mod validate { let result = compiler .parse_program(&source, FileName::Custom(name.into()), &[]) + .and_then(|_| compiler.add_import_stubs()) .and_then(|_| compiler.intermediate_passes().map(|_| ())); if let Err(e) = result { diff --git a/crates/fmt/tests/source/expr_method_chain.leo b/crates/fmt/tests/source/expr_method_chain.leo index 5e00fcef318..e57235d964a 100644 --- a/crates/fmt/tests/source/expr_method_chain.leo +++ b/crates/fmt/tests/source/expr_method_chain.leo @@ -4,12 +4,12 @@ final fn use_special( caller_addr : address ) { - let h : u32 = block.height + let h : u32 = std::ctx::block_height() ; let t : i64 = - block.timestamp + std::ctx::block_timestamp() ; - let n : u16 = network.id; + let n : u16 = std::ctx::network_id(); } final fn do_deposit( @@ -60,10 +60,10 @@ program test.aleo : address , public amount : u64 ) -> Final { - let caller : address = self.caller + let caller : address = std::ctx::caller() ; let signer : address - = self.signer; + = std::ctx::signer(); return final { do_deposit( sender , diff --git a/crates/fmt/tests/source/record_basic.leo b/crates/fmt/tests/source/record_basic.leo index 6e11d30e407..1dbcd7948ea 100644 --- a/crates/fmt/tests/source/record_basic.leo +++ b/crates/fmt/tests/source/record_basic.leo @@ -3,7 +3,7 @@ program test.aleo { fn mint( public amt : u64 ) -> Token { - return Token { owner : self.caller , amount : amt } ; + return Token { owner : std::ctx::caller() , amount : amt } ; } record Token diff --git a/crates/fmt/tests/target/expr_method_chain.leo b/crates/fmt/tests/target/expr_method_chain.leo index 608ee17cfe3..37a684e6a96 100644 --- a/crates/fmt/tests/target/expr_method_chain.leo +++ b/crates/fmt/tests/target/expr_method_chain.leo @@ -3,9 +3,9 @@ struct Wrapper { } final fn use_special(caller_addr: address) { - let h: u32 = block.height; - let t: i64 = block.timestamp; - let n: u16 = network.id; + let h: u32 = std::ctx::block_height(); + let t: i64 = std::ctx::block_timestamp(); + let n: u16 = std::ctx::network_id(); } final fn do_deposit(sender: address, amount: u64) { @@ -31,8 +31,8 @@ program test.aleo { mapping balances: address => u64; fn deposit(public sender: address, public amount: u64) -> Final { - let caller: address = self.caller; - let signer: address = self.signer; + let caller: address = std::ctx::caller(); + let signer: address = std::ctx::signer(); return final { do_deposit(sender, amount); }; } } diff --git a/crates/fmt/tests/target/record_basic.leo b/crates/fmt/tests/target/record_basic.leo index 294b7c4c9e2..6b1bce9aed7 100644 --- a/crates/fmt/tests/target/record_basic.leo +++ b/crates/fmt/tests/target/record_basic.leo @@ -3,7 +3,7 @@ program test.aleo { constructor() {} fn mint(public amt: u64) -> Token { - return Token { owner: self.caller, amount: amt }; + return Token { owner: std::ctx::caller(), amount: amt }; } record Token { diff --git a/crates/leo-std/src/leo/ctx.leo b/crates/leo-std/src/leo/ctx.leo index b28985782fa..1e13dd4f4ec 100644 --- a/crates/leo-std/src/leo/ctx.leo +++ b/crates/leo-std/src/leo/ctx.leo @@ -16,6 +16,8 @@ fn addr() -> address { // Use `caller` for trust decisions about who is asking for the current // operation. Use `signer` when the decision should track the // originator of the entire transaction. +@offchain +@_caller_annotation fn caller() -> address { return _self_caller(); } @@ -23,6 +25,7 @@ fn caller() -> address { // Returns the address that signed the outer transaction. Unlike `caller`, // this never changes during cross-program calls: it always points to the // off-chain agent who authorized the whole call graph. +@offchain fn signer() -> address { return _self_signer(); } @@ -30,7 +33,7 @@ fn signer() -> address { // Returns the on-chain identifier of this program. The id is an Aleo address // derived from the program's source and is the same value users see in block // explorers. -final fn id() -> address { +fn id() -> address { return _self_id(); } diff --git a/crates/leo-std/src/leo/prog.leo b/crates/leo-std/src/leo/prog.leo new file mode 100644 index 00000000000..d030d8492df --- /dev/null +++ b/crates/leo-std/src/leo/prog.leo @@ -0,0 +1,43 @@ +// On-chain metadata accessors for imported programs. +// +// Each function in this module reads finalize-store state of a *named* +// program — the program identifier is a const generic argument, so it is +// fixed at compile time. Use these to gate logic on the on-chain version, +// checksum, or ownership of a dependency program. + +// Returns the 32-byte deployment checksum of the program identified by +// `PROG`. The checksum changes only when the program is upgraded with +// new bytecode, so two programs with the same source and dependencies +// will agree on this value. +@_program_id_arg +final fn checksum::[PROG: address]() -> [u8; 32] { + return _program_checksum(PROG); +} + +// Returns the deployment edition of the program identified by `PROG`. +// Edition `0` is the initial deployment; every upgrade increments it. +// Useful for guarding logic against specific upgrade versions of a +// dependency. +@_program_id_arg +final fn edition::[PROG: address]() -> u16 { + return _program_edition(PROG); +} + +// Returns the address that owns the program identified by `PROG` — +// typically the account that performed the deployment. +// +// Programs deployed before the upgradability feature shipped do not have +// an owner; reading this value on such a program halts at runtime. +@_program_id_arg +final fn program_owner::[PROG: address]() -> address { + return _program_owner(PROG); +} + +// Returns the 32-byte checksum of a specific function (`FN_NAME`) inside +// the program identified by `PROG`. Useful for asserting that a particular +// function of a dependency program has not changed between upgrades. +@_program_id_arg +@_callable_function_arg +final fn function_checksum::[PROG: address, FN_NAME: identifier]() -> [u8; 32] { + return _function_checksum(PROG, FN_NAME); +} diff --git a/crates/leo-std/src/lib.rs b/crates/leo-std/src/lib.rs index 9ea8f8eb820..84104f6e6db 100644 --- a/crates/leo-std/src/lib.rs +++ b/crates/leo-std/src/lib.rs @@ -54,6 +54,7 @@ const SIG_LEO: &str = include_str!("leo/sig.leo"); const SERIALIZE_LEO: &str = include_str!("leo/serialize.leo"); const GRP_LEO: &str = include_str!("leo/grp.leo"); const CTX_LEO: &str = include_str!("leo/ctx.leo"); +const PROG_LEO: &str = include_str!("leo/prog.leo"); /// Entry source of the standard library (contents of `lib.leo`). pub fn entry_source() -> &'static str { @@ -94,6 +95,7 @@ pub fn modules() -> &'static [(&'static str, &'static str)] { ("serialize.leo", SERIALIZE_LEO), ("grp.leo", GRP_LEO), ("ctx.leo", CTX_LEO), + ("prog.leo", PROG_LEO), ] } diff --git a/crates/leo/src/cli/cli.rs b/crates/leo/src/cli/cli.rs index d606af20b2b..3549d9cae5e 100644 --- a/crates/leo/src/cli/cli.rs +++ b/crates/leo/src/cli/cli.rs @@ -2191,7 +2191,7 @@ program inner_1.aleo { } fn inner_1_main(public a: u32, b: u32, c: ex_struct) -> inner_1_record { return inner_1_record { - owner: self.caller, + owner: std::ctx::caller(), val: c.arg1, }; } @@ -2210,7 +2210,7 @@ program inner_2.aleo { fn inner_2_main(public a: u32, b: u32) -> inner_2_record { let c: u32 = a + b; return inner_2_record { - owner: self.caller, + owner: std::ctx::caller(), val: a, }; } @@ -2371,7 +2371,7 @@ program outer_2.aleo { inner_2.aleo::Yo_Consumer(inner_2.aleo::Yo()); let h: inner_2.aleo::Yoo = inner_2.aleo::Yo(); let i: inner_2.aleo::Goo = inner_2.aleo::Goo_creator(); - let j: Hello = Hello {owner: self.signer, a:1u32}; + let j: Hello = Hello {owner: std::ctx::signer(), a:1u32}; return (h, j); } @@ -2425,7 +2425,7 @@ program inner_2.aleo { return Foo {a: a, b: b, c: Boo {a:1u32, b:1u32}}; } fn Yo()-> Yoo { - return Yoo {owner: self.signer, a:1u32}; + return Yoo {owner: std::ctx::signer(), a:1u32}; } fn Yo_Consumer(a: Yoo)->u32 { return a.a; diff --git a/crates/parser-rowan/src/lexer.rs b/crates/parser-rowan/src/lexer.rs index a66d4bdf23d..ec1842c936a 100644 --- a/crates/parser-rowan/src/lexer.rs +++ b/crates/parser-rowan/src/lexer.rs @@ -336,6 +336,7 @@ fn ident_to_kind(s: &str) -> SyntaxKind { "private" => KW_PRIVATE, "as" => KW_AS, "self" => KW_SELF, + "Self" => KW_SELF_UPPER, "assert" => KW_ASSERT, "assert_eq" => KW_ASSERT_EQ, "assert_neq" => KW_ASSERT_NEQ, diff --git a/crates/parser-rowan/src/parser/expressions.rs b/crates/parser-rowan/src/parser/expressions.rs index ed805f2238e..0af61f8bd6b 100644 --- a/crates/parser-rowan/src/parser/expressions.rs +++ b/crates/parser-rowan/src/parser/expressions.rs @@ -454,9 +454,12 @@ impl Parser<'_, '_> { // Identifier, path, or struct literal IDENT | KW_FINAL_UPPER => self.parse_ident_expr(opts), - // Self access + // `self` access KW_SELF => self.parse_self_expr(), + // `Self` is reserved for future use + KW_SELF_UPPER => self.parse_self_upper_expr(), + // Block expressions (block, network) KW_BLOCK => self.parse_block_access(), KW_NETWORK => self.parse_network_access(), @@ -817,6 +820,13 @@ impl Parser<'_, '_> { Some(m.complete(self, BLOCK_KW_EXPR)) } + /// Parse a use of the reserved `Self` keyword. + fn parse_self_upper_expr(&mut self) -> Option { + let m = self.start(); + self.bump_any(); // Self + Some(m.complete(self, SELF_UPPER_EXPR)) + } + /// Parse `network.id` access. fn parse_network_access(&mut self) -> Option { let m = self.start(); diff --git a/crates/parser-rowan/src/syntax_kind.rs b/crates/parser-rowan/src/syntax_kind.rs index 3b63bb26a09..6b8094d5d75 100644 --- a/crates/parser-rowan/src/syntax_kind.rs +++ b/crates/parser-rowan/src/syntax_kind.rs @@ -223,6 +223,8 @@ define_syntax_kinds! { KW_AS, /// `self` KW_SELF, + /// `Self` + KW_SELF_UPPER, /// `assert` KW_ASSERT, /// `assert_eq` @@ -523,6 +525,8 @@ define_syntax_kinds! { PROGRAM_REF_EXPR, /// Self expression: `self` SELF_EXPR, + /// `Self` expression. + SELF_UPPER_EXPR, /// Block keyword expression: `block` BLOCK_KW_EXPR, /// Network keyword expression: `network` @@ -651,6 +655,7 @@ impl SyntaxKind { | KW_PRIVATE | KW_AS | KW_SELF + | KW_SELF_UPPER | KW_ASSERT | KW_ASSERT_EQ | KW_ASSERT_NEQ @@ -745,6 +750,7 @@ impl SyntaxKind { | PATH_LOCATOR_EXPR | PROGRAM_REF_EXPR | SELF_EXPR + | SELF_UPPER_EXPR | BLOCK_KW_EXPR | NETWORK_KW_EXPR | PAREN_EXPR @@ -920,6 +926,7 @@ impl SyntaxKind { KW_PRIVATE => "'private'", KW_AS => "'as'", KW_SELF => "'self'", + KW_SELF_UPPER => "'Self'", KW_ASSERT => "'assert'", KW_ASSERT_EQ => "'assert_eq'", KW_ASSERT_NEQ => "'assert_neq'", diff --git a/crates/parser/src/errors.rs b/crates/parser/src/errors.rs index 90534febf21..28ffd969ebd 100644 --- a/crates/parser/src/errors.rs +++ b/crates/parser/src/errors.rs @@ -163,6 +163,24 @@ pub(crate) fn multiple_program_declarations(span: leo_span::Span) -> Formatted { .with_help("Remove the duplicate `program` block. Only one is allowed per program.") } +pub(crate) fn obsolete_context_access(old: impl Display, replacement: impl Display, span: leo_span::Span) -> Formatted { + Formatted::error(CODE_PREFIX, CODE_MASK + 56, format!("the `{old}` syntax has been removed"), span).with_help( + format!("Use `{replacement}` instead. Execution-context accessors now live in the `std::ctx` module."), + ) +} + +pub(crate) fn obsolete_context_keyword(keyword: impl Display, span: leo_span::Span) -> Formatted { + Formatted::error(CODE_PREFIX, CODE_MASK + 57, format!("`{keyword}` is no longer a valid expression"), span) + .with_help(format!( + "`{keyword}` is reserved and no longer denotes an execution-context value. Use functions from the `std::ctx` module to access caller, signer, block, or network information." + )) +} + +pub(crate) fn reserved_identifier(name: impl Display, span: leo_span::Span) -> Formatted { + Formatted::error(CODE_PREFIX, CODE_MASK + 58, format!("`{name}` is reserved for future use"), span) + .with_help(format!("Rename this identifier. `{name}` is reserved by the language for an upcoming feature.")) +} + // Parser warnings pub(crate) fn record_prototype_redundant(record_name: impl Display, span: leo_span::Span) -> Formatted { diff --git a/crates/parser/src/rowan.rs b/crates/parser/src/rowan.rs index fe13b433783..b6c538c998b 100644 --- a/crates/parser/src/rowan.rs +++ b/crates/parser/src/rowan.rs @@ -561,6 +561,10 @@ impl<'a> ConversionContext<'a> { SELF_EXPR => self.keyword_expr_to_path(node, sym::SelfLower)?, BLOCK_KW_EXPR => self.keyword_expr_to_path(node, sym::block)?, NETWORK_KW_EXPR => self.keyword_expr_to_path(node, sym::network)?, + SELF_UPPER_EXPR => { + self.handler.emit_err(crate::errors::reserved_identifier("Self", self.trimmed_span(node))); + self.error_expression(span) + } PAREN_EXPR => { // Parenthesized expression - just unwrap if let Some(inner) = children(node).find(|n| n.kind().is_expression()) { @@ -884,6 +888,25 @@ impl<'a> ConversionContext<'a> { } .into()); } + // `Program::*` used to desugar to the program-metadata intrinsics. The replacement + // lives in `std::prog::*`; emit a tailored migration error. + if module == sym::ProgramCore { + let replacement = match name { + sym::checksum => Some("std::prog::checksum::[PROG_ID]()"), + sym::edition => Some("std::prog::edition::[PROG_ID]()"), + sym::program_owner => Some("std::prog::program_owner::[PROG_ID]()"), + sym::function_checksum => Some("std::prog::function_checksum::[PROG_ID, FN_NAME]()"), + _ => None, + }; + if let Some(replacement) = replacement { + self.handler.emit_err(crate::errors::obsolete_context_access( + format!("Program::{}", name), + replacement, + span, + )); + return Ok(self.error_expression(span)); + } + } } // Bare intrinsic calls (e.g. `_dynamic_call::[u64](args)`). @@ -1122,7 +1145,12 @@ impl<'a> ConversionContext<'a> { let (inner, first_child_kind) = match children(node).find(|n| n.kind().is_expression()) { Some(n) => { let kind = n.kind(); - (self.to_expression(&n)?, kind) + let lowered = if matches!(kind, SELF_EXPR | BLOCK_KW_EXPR | NETWORK_KW_EXPR) { + self.error_expression(self.trimmed_span(&n)) + } else { + self.to_expression(&n)? + }; + (lowered, kind) } None => { self.emit_unexpected_str("expression in field access", node.text(), span); @@ -1131,7 +1159,7 @@ impl<'a> ConversionContext<'a> { }; // Get the field name (token after DOT). - // Field names can be identifiers or keywords (e.g. `self.address`). + // Field names can be identifiers or keywords. let field_token = match find_name_after_dot(node) { Some(token) => token, None => { @@ -1152,37 +1180,42 @@ impl<'a> ConversionContext<'a> { return Ok(leo_ast::Literal::address(full_name, span, id).into()); } - // Check for special accesses: self.caller, block.height, etc. + // `self.X`, `block.X`, and `network.X` used to be sugar for execution-context + // intrinsics. The sugar has been removed; the same values are now reached + // through the `std::ctx` module. Emit a targeted migration error that names + // the replacement. let field_name = Symbol::intern(field_token.text()); - - let special = match (first_child_kind, field_name) { - (SELF_EXPR, sym::address) => Some(sym::_self_address), - (SELF_EXPR, sym::caller) => Some(sym::_self_caller), - (SELF_EXPR, sym::checksum) => Some(sym::_self_checksum), - (SELF_EXPR, sym::edition) => Some(sym::_self_edition), - (SELF_EXPR, sym::id) => Some(sym::_self_id), - (SELF_EXPR, sym::program_owner) => Some(sym::_self_program_owner), - (SELF_EXPR, sym::signer) => Some(sym::_self_signer), - (BLOCK_KW_EXPR, sym::height) => Some(sym::_block_height), - (BLOCK_KW_EXPR, sym::timestamp) => Some(sym::_block_timestamp), - (NETWORK_KW_EXPR, sym::id) => Some(sym::_network_id), - (SELF_EXPR | BLOCK_KW_EXPR | NETWORK_KW_EXPR, _) => { - self.handler.emit_err(crate::errors::custom("Unsupported special access", span)); - return Ok(self.error_expression(span)); - } + let removed_access = match (first_child_kind, field_name) { + (SELF_EXPR, sym::address) => Some(("self.address", "std::ctx::addr()")), + (SELF_EXPR, sym::caller) => Some(("self.caller", "std::ctx::caller()")), + (SELF_EXPR, sym::checksum) => Some(("self.checksum", "std::ctx::checksum()")), + (SELF_EXPR, sym::edition) => Some(("self.edition", "std::ctx::edition()")), + (SELF_EXPR, sym::id) => Some(("self.id", "std::ctx::id()")), + (SELF_EXPR, sym::program_owner) => Some(("self.program_owner", "std::ctx::program_owner()")), + (SELF_EXPR, sym::signer) => Some(("self.signer", "std::ctx::signer()")), + (BLOCK_KW_EXPR, sym::height) => Some(("block.height", "std::ctx::block_height()")), + (BLOCK_KW_EXPR, sym::timestamp) => Some(("block.timestamp", "std::ctx::block_timestamp()")), + (NETWORK_KW_EXPR, sym::id) => Some(("network.id", "std::ctx::network_id()")), _ => None, }; - - if let Some(intrinsic_name) = special { - return Ok(self.intrinsic_expression(intrinsic_name, Vec::new(), span)); + if let Some((old, replacement)) = removed_access { + self.handler.emit_err(crate::errors::obsolete_context_access(old, replacement, span)); + return Ok(self.error_expression(span)); + } + if matches!(first_child_kind, SELF_EXPR | BLOCK_KW_EXPR | NETWORK_KW_EXPR) { + let keyword = match first_child_kind { + SELF_EXPR => "self", + BLOCK_KW_EXPR => "block", + NETWORK_KW_EXPR => "network", + _ => unreachable!(), + }; + self.handler.emit_err(crate::errors::obsolete_context_keyword(keyword, span)); + return Ok(self.error_expression(span)); } - // Field token may be an identifier or keyword (e.g. `self.address`). - let name = leo_ast::Identifier { - name: Symbol::intern(field_token.text()), - span: self.token_span(&field_token), - id: self.builder.next_id(), - }; + // Field token may be an identifier or keyword (e.g. `obj.aleo`). + let field_span = self.token_span(&field_token); + let name = leo_ast::Identifier { name: field_name, span: field_span, id: self.builder.next_id() }; Ok(leo_ast::MemberAccess { inner, name, span, id }.into()) } @@ -1528,12 +1561,19 @@ impl<'a> ConversionContext<'a> { Ok(leo_ast::Expression::Path(path)) } - /// Convert a keyword expression (SELF_EXPR, BLOCK_KW_EXPR, NETWORK_KW_EXPR) to a Path. + /// Handle a bare reference to one of the removed context keywords + /// (`self`, `block`, `network`). The sugar that turned these into expressions + /// has been replaced by the `std::ctx` module, so emit a migration error. fn keyword_expr_to_path(&self, node: &SyntaxNode, name: Symbol) -> Result { let span = self.trimmed_span(node); - let ident = leo_ast::Identifier { name, span, id: self.builder.next_id() }; - let path = leo_ast::Path::new(None, Vec::new(), ident, span, self.builder.next_id()); - Ok(leo_ast::Expression::Path(path)) + let keyword = match name { + sym::SelfLower => "self", + sym::block => "block", + sym::network => "network", + _ => unreachable!("keyword_expr_to_path called with non-context keyword"), + }; + self.handler.emit_err(crate::errors::obsolete_context_keyword(keyword, span)); + Ok(self.error_expression(span)) } /// Convert a FINAL_EXPR node to an Expression. diff --git a/crates/passes/src/errors/type_checker.rs b/crates/passes/src/errors/type_checker.rs index 704cc9140f5..a5b9363a0d0 100644 --- a/crates/passes/src/errors/type_checker.rs +++ b/crates/passes/src/errors/type_checker.rs @@ -1092,10 +1092,10 @@ pub(crate) fn caller_as_record_owner(record_name: impl Display, span: Span) -> F Formatted::warning( CODE_PREFIX, CODE_MASK + 4, - format!("`self.caller` used as the owner of record `{record_name}`"), + format!("`std::ctx::caller()` used as the owner of record `{record_name}`"), span, ) - .with_help("`self.caller` may refer to a program address, which cannot spend records. Use `self.signer` if you want the user that initiated the transaction.") + .with_help("`std::ctx::caller()` may return a program address, which cannot spend records. Use `std::ctx::signer()` if you want the user that initiated the transaction.") } pub(crate) fn no_inline_ignored(name: impl Display, reason: impl Display, span: Span) -> Formatted { diff --git a/crates/passes/src/type_checking/ast.rs b/crates/passes/src/type_checking/ast.rs index b575608758e..d78cbace8fb 100644 --- a/crates/passes/src/type_checking/ast.rs +++ b/crates/passes/src/type_checking/ast.rs @@ -1164,8 +1164,8 @@ impl AstVisitor for TypeCheckingVisitor<'_> { if matches!(func.variant, Variant::EntryPoint) && callee_program == self.scope_state.unit_name.unwrap() { self.emit_err(crate::errors::type_checker::cannot_invoke_call_to_local_entry_point_fn(input.span)); - } else if matches!(func.variant, Variant::View) && self.async_block_id.is_none() { - // Views are only callable from inside a `final {}` block. + } else if matches!(func.variant, Variant::View | Variant::FinalFn) && self.async_block_id.is_none() { + // Views and FinalFns are only callable from inside a `final {}` block when inside an EntryPoint. self.emit_err(crate::errors::type_checker::can_only_call_inline_function( "a transition body outside a `final {}` block", input.span, @@ -1183,6 +1183,64 @@ impl AstVisitor for TypeCheckingVisitor<'_> { return Type::Err; } + // `@offchain` propagates an off-chain-only restriction from the callee to its caller: the + // call is rejected in finalize/view contexts and inside `final {}` async blocks. This is how + // wrappers like `std::ctx::caller()` over the `_self_caller` intrinsic regain the access-scope + // rule that the parser used to enforce on the desugared `self.caller` syntax. + if func.annotations.iter().any(|a| a.identifier.name == sym::offchain) { + let name = format!("{}()", input.function); + self.check_access_allowed(&name, AccessScope::OffchainCaller, input.span); + } + + // `@_program_id_arg` marks a compiler-internal wrapper whose first const generic argument + // is the program-ID literal threaded into a program-metadata intrinsic. Validate the + // literal shape at the user's call site (the wrapper body never sees the substituted + // literal because the relevant TypeChecking pass runs on the un-substituted template). + let program_id = if func.annotations.iter().any(|a| a.identifier.name == sym::_program_id_arg) { + let program_id_regex = regex::Regex::new(r"^[a-zA-Z][a-zA-Z0-9_]{0,30}\.aleo$").unwrap(); + match input.const_arguments.first() { + Some(Expression::Literal(Literal { variant: LiteralVariant::Address(s), .. })) + if program_id_regex.is_match(s) => + { + Some(s.clone()) + } + Some(arg) => { + self.emit_err(crate::errors::type_checker::custom( + format!("`{}` must be called on a program ID, e.g. `foo.aleo`", input.function), + arg.span(), + )); + None + } + None => None, + } + } else { + None + }; + + // `@_callable_function_arg` marks a wrapper whose second const generic argument names a + // function in the program identified by the first const arg. Verify it resolves to an + // entry or view function of that program (closures and `final fn`s have no stable + // identity in the compiled bytecode). + if func.annotations.iter().any(|a| a.identifier.name == sym::_callable_function_arg) + && let Some(component_arg) = input.const_arguments.get(1) + && let Expression::Literal(Literal { variant: LiteralVariant::Identifier(component), .. }) = component_arg + && let Some(program_id) = &program_id + { + let location = Location::new(Symbol::intern(program_id), vec![Symbol::intern(component.as_str())]); + let current_unit = self.scope_state.unit_name.expect("type checking runs within a program"); + let is_entry_or_view = self + .state + .symbol_table + .lookup_function(current_unit, &location) + .is_some_and(|symbol| symbol.function.variant.is_externally_callable()); + if !is_entry_or_view { + self.emit_err(crate::errors::type_checker::custom( + format!("`{component}` must be an entry function or a view function of `{program_id}`"), + component_arg.span(), + )); + } + } + // Async functions return a single future. let mut ret = if func.variant == Variant::Finalize { // Async functions always return futures. @@ -1670,17 +1728,33 @@ impl AstVisitor for TypeCheckingVisitor<'_> { .emit_err(crate::errors::type_checker::records_not_allowed_inside_final(input.span())); } - // Records where the `owner` is `self.caller` can be problematic because `self.caller` can be a program - // address and programs can't spend records. Emit a warning in this case. + // Records where the `owner` resolves to the `_self_caller` intrinsic can be problematic: + // the caller may be a program address, and programs can't spend records. Emit a warning + // when the owner expression is either the raw `_self_caller()` call or a call to a + // wrapper function carrying the compiler-internal `@_caller_annotation` (e.g. + // `std::ctx::caller()`). Resolving via the annotation keeps the check working even if + // the stdlib wrapper is renamed or moved. // // Multiple occurrences of `owner` here is an error but that should be flagged somewhere else. input.members.iter().filter(|init| init.identifier.name == sym::owner).for_each(|init| { - if let Some(Expression::Intrinsic(intr)) = &init.expression - && let IntrinsicExpression { name: sym::_self_caller, .. } = &**intr - { + let Some(expr) = &init.expression else { return }; + let is_caller_intrinsic = match expr { + Expression::Intrinsic(intr) => intr.name == sym::_self_caller, + Expression::Call(call) => call + .function + .try_global_location() + .and_then(|loc| { + self.state.symbol_table.lookup_function(self.scope_state.unit_name.unwrap(), loc) + }) + .is_some_and(|func_sym| { + func_sym.function.annotations.iter().any(|a| a.identifier.name == sym::_caller_annotation) + }), + _ => false, + }; + if is_caller_intrinsic { self.state.handler.emit_warning_once( - intr.span(), - crate::errors::type_checker::caller_as_record_owner(input.path.clone(), intr.span()), + expr.span(), + crate::errors::type_checker::caller_as_record_owner(input.path.clone(), expr.span()), ); } }); diff --git a/crates/passes/src/type_checking/program.rs b/crates/passes/src/type_checking/program.rs index bcef51f1468..52351f20d17 100644 --- a/crates/passes/src/type_checking/program.rs +++ b/crates/passes/src/type_checking/program.rs @@ -284,7 +284,13 @@ impl UnitVisitor for TypeCheckingVisitor<'_> { // Restrictions for const parameters if !matches!( const_param.type_(), - Type::Boolean | Type::Integer(_) | Type::Address | Type::Scalar | Type::Group | Type::Field + Type::Boolean + | Type::Integer(_) + | Type::Address + | Type::Scalar + | Type::Group + | Type::Field + | Type::Identifier ) { slf.emit_err(crate::errors::type_checker::bad_const_generic_type( const_param.type_(), @@ -518,7 +524,17 @@ impl UnitVisitor for TypeCheckingVisitor<'_> { // Check that the function's annotations are valid. for annotation in function.annotations.iter() { - if !matches!(annotation.identifier.name, sym::test | sym::should_fail | sym::no_inline | sym::inline) { + if !matches!( + annotation.identifier.name, + sym::test + | sym::should_fail + | sym::no_inline + | sym::inline + | sym::offchain + | sym::_caller_annotation + | sym::_program_id_arg + | sym::_callable_function_arg + ) { self.emit_err(crate::errors::type_checker::unknown_annotation(annotation, annotation.span)) } } diff --git a/crates/passes/src/type_checking/visitor.rs b/crates/passes/src/type_checking/visitor.rs index ce969832361..ffdfa6deb1c 100644 --- a/crates/passes/src/type_checking/visitor.rs +++ b/crates/passes/src/type_checking/visitor.rs @@ -568,9 +568,6 @@ impl TypeCheckingVisitor<'_> { } }; - // Define a regex to match valid program IDs. - let program_id_regex = regex::Regex::new(r"^[a-zA-Z][a-zA-Z0-9_]{0,30}\.aleo$").unwrap(); - fn struct_not_supported(_: &T) -> anyhow::Result { bail!("structs are not supported") } @@ -1328,23 +1325,12 @@ impl TypeCheckingVisitor<'_> { )), )), Intrinsic::ProgramChecksum => { - // Get the argument type, expression, and span. + // The compile-time program-ID literal check fires at the `std::prog::*` call + // site (via `@_program_id_arg`), so the body of the wrapper only needs the + // address-type assertion here. let (type_, expression) = &arguments[0]; let span = expression.span(); - // Check that the expression is a program ID. - match expression { - Expression::Literal(Literal { variant: LiteralVariant::Address(s), .. }) - if program_id_regex.is_match(s) => {} - _ => { - self.emit_err(crate::errors::type_checker::custom( - "`Program::checksum` must be called on a program ID, e.g. `foo.aleo`", - span, - )); - } - } - // Verify that the argument is a string. self.assert_type(type_, &Type::Address, span); - // Return the type. Type::Array(ArrayType::new( Type::Integer(IntegerType::U8), Expression::Literal(Literal::integer( @@ -1356,99 +1342,26 @@ impl TypeCheckingVisitor<'_> { )) } Intrinsic::ProgramEdition => { - // Get the argument type, expression, and span. let (type_, expression) = &arguments[0]; let span = expression.span(); - // Check that the expression is a member access. - match expression { - Expression::Literal(Literal { variant: LiteralVariant::Address(s), .. }) - if program_id_regex.is_match(s) => {} - _ => { - self.emit_err(crate::errors::type_checker::custom( - "`Program::edition` must be called on a program ID, e.g. `foo.aleo`", - span, - )); - } - } - // Verify that the argument is a string. self.assert_type(type_, &Type::Address, span); - // Return the type. Type::Integer(IntegerType::U16) } Intrinsic::ProgramOwner => { - // Get the argument type, expression, and span. let (type_, expression) = &arguments[0]; let span = expression.span(); - // Check that the expression is a member access. - match expression { - Expression::Literal(Literal { variant: LiteralVariant::Address(s), .. }) - if program_id_regex.is_match(s) => {} - _ => { - self.emit_err(crate::errors::type_checker::custom( - "`Program::program_owner` must be called on a program ID, e.g. `foo.aleo`", - span, - )); - } - } - // Verify that the argument is a string. self.assert_type(type_, &Type::Address, span); - // Return the type. Type::Address } Intrinsic::FunctionChecksum => { // The first argument is the program ID, the second the component name. + // Shape validation happens at the `std::prog::function_checksum` call site (via + // the `@_program_id_arg` annotation); the const-generic type checks already + // enforce `address` and `identifier` shapes on the parameters. let (program_type, program_expr) = &arguments[0]; - let program_span = program_expr.span(); - // Check that the first argument is a program ID. - let program_id = match program_expr { - Expression::Literal(Literal { variant: LiteralVariant::Address(s), .. }) - if program_id_regex.is_match(s) => - { - Some(s.clone()) - } - _ => { - self.emit_err(crate::errors::type_checker::custom( - "`Program::function_checksum` must be called on a program ID, e.g. `foo.aleo`", - program_span, - )); - None - } - }; - self.assert_type(program_type, &Type::Address, program_span); - // Check that the second argument is an identifier literal naming the component, e.g. `'foo'`. + self.assert_type(program_type, &Type::Address, program_expr.span()); let (component_type, component_expr) = &arguments[1]; - let component_span = component_expr.span(); - let component = match component_expr { - Expression::Literal(Literal { variant: LiteralVariant::Identifier(name), .. }) => { - Some(name.clone()) - } - _ => { - self.emit_err(crate::errors::type_checker::custom( - "the function name must be an identifier literal, e.g. `'foo'`", - component_span, - )); - None - } - }; - self.assert_type(component_type, &Type::Identifier, component_span); - // Checksums exist only for externally-callable components — entry and view functions. - // Closures and `final fn`s are inlining artifacts with no stable identity, so reject - // anything that does not resolve to an entry or view function of the named (imported) program. - if let (Some(program_id), Some(component)) = (program_id, component) { - let location = Location::new(Symbol::intern(&program_id), vec![Symbol::intern(&component)]); - let current_unit = self.scope_state.unit_name.expect("type checking runs within a program"); - let is_entry_or_view = self - .state - .symbol_table - .lookup_function(current_unit, &location) - .is_some_and(|symbol| symbol.function.variant.is_externally_callable()); - if !is_entry_or_view { - self.emit_err(crate::errors::type_checker::custom( - format!("`{component}` must be an entry function or a view function of `{program_id}`"), - component_span, - )); - } - } + self.assert_type(component_type, &Type::Identifier, component_expr.span()); // Return the type. Type::Array(ArrayType::new( Type::Integer(IntegerType::U8), @@ -1592,7 +1505,7 @@ impl TypeCheckingVisitor<'_> { Intrinsic::SelfAddress => Type::Address, Intrinsic::SelfCaller => { // Check that the operation is not invoked in a `finalize` block. - self.check_access_allowed("self.caller", AccessScope::OffchainCaller, function_span); + self.check_access_allowed("std::ctx::caller()", AccessScope::OffchainCaller, function_span); Type::Address } Intrinsic::SelfChecksum => Type::Array(ArrayType::new( @@ -1608,28 +1521,28 @@ impl TypeCheckingVisitor<'_> { Intrinsic::SelfId => Type::Address, Intrinsic::SelfProgramOwner => { // Check that the operation is only invoked in a `finalize` block. - self.check_access_allowed("program_owner", AccessScope::FinalizeWrite, function_span); + self.check_access_allowed("std::ctx::program_owner()", AccessScope::FinalizeWrite, function_span); Type::Address } Intrinsic::SelfSigner => { // Check that operation is not invoked in a `finalize` block. - self.check_access_allowed("self.signer", AccessScope::OffchainCaller, function_span); + self.check_access_allowed("std::ctx::signer()", AccessScope::OffchainCaller, function_span); Type::Address } Intrinsic::BlockHeight => { // Check that the operation is invoked in a `finalize` block or a view. // Views see the latest block height via FinalizeGlobalState::for_view. - self.check_access_allowed("block.height", AccessScope::FinalizeRead, function_span); + self.check_access_allowed("std::ctx::block_height()", AccessScope::FinalizeRead, function_span); Type::Integer(IntegerType::U32) } Intrinsic::BlockTimestamp => { // Check that the operation is invoked in a `finalize` block. Rejected in view fns. - self.check_access_allowed("block.timestamp", AccessScope::FinalizeWrite, function_span); + self.check_access_allowed("std::ctx::block_timestamp()", AccessScope::FinalizeWrite, function_span); Type::Integer(IntegerType::I64) } Intrinsic::NetworkId => { // Check that the operation is not invoked outside a `finalize` block or a view. - self.check_access_allowed("network.id", AccessScope::FinalizeRead, function_span); + self.check_access_allowed("std::ctx::network_id()", AccessScope::FinalizeRead, function_span); Type::Integer(IntegerType::U16) } // Dynamic dispatch intrinsics are handled in visit_intrinsic before check_intrinsic. @@ -2238,7 +2151,9 @@ impl TypeCheckingVisitor<'_> { } // Const generic parameters can only be monomorphized at inline call sites. Reject them on - // any function that will never be inlined or that does not support inlining. + // any function that will never be inlined or that does not support inlining. `final fn` + // helpers are always inlined into their `final {}` callsite, so they support const + // generics the same way regular `fn` helpers do. if !function.const_parameters.is_empty() { if function.annotations.iter().any(|a| a.identifier.name == sym::no_inline) { self.emit_err(crate::errors::type_checker::cannot_have_const_generics( @@ -2250,11 +2165,6 @@ impl TypeCheckingVisitor<'_> { "entry point functions", function.identifier.span(), )); - } else if matches!(self.scope_state.variant, Some(Variant::FinalFn)) { - self.emit_err(crate::errors::type_checker::cannot_have_const_generics( - "`final fn` functions", - function.identifier.span(), - )); } else if matches!(self.scope_state.variant, Some(Variant::View)) { self.emit_err(crate::errors::type_checker::cannot_have_const_generics( "`view fn` functions", @@ -2276,7 +2186,13 @@ impl TypeCheckingVisitor<'_> { // Restrictions for const parameters if !matches!( const_param.type_(), - Type::Boolean | Type::Integer(_) | Type::Address | Type::Scalar | Type::Group | Type::Field + Type::Boolean + | Type::Integer(_) + | Type::Address + | Type::Scalar + | Type::Group + | Type::Field + | Type::Identifier ) { self.emit_err(crate::errors::type_checker::bad_const_generic_type( const_param.type_(), diff --git a/crates/span/symbols.txt b/crates/span/symbols.txt index cdfb30e981a..2baa4ee0a29 100644 --- a/crates/span/symbols.txt +++ b/crates/span/symbols.txt @@ -737,6 +737,10 @@ admin key no_inline inline +offchain +_caller_annotation +_program_id_arg +_callable_function_arg // annotation keys private_key diff --git a/documentation/cli/build.md b/documentation/cli/build.md index e9a6733b089..c45899e8ac7 100644 --- a/documentation/cli/build.md +++ b/documentation/cli/build.md @@ -29,7 +29,7 @@ The build also generates an **ABI file** at `build/{PROGRAM_NAME}/abi.json` desc ## Checksums -The program checksum and the checksum of each entry and view function are the values that the [`Program::function_checksum`](../language/programs_in_practice/intrinsics.md) intrinsic targets, so they are useful when writing a [constructor](../language/structure.md#constructor) that pins specific functions across upgrades. To print them, pass `--checksums`: +The program checksum and the checksum of each entry and view function are the values that the [`std::prog::function_checksum`](../language/standard_library.md#stdprog) stdlib function returns, so they are useful when writing a [constructor](../language/structure.md#constructor) that pins specific functions across upgrades. To print them, pass `--checksums`: ```bash leo build --checksums @@ -50,7 +50,7 @@ Each checksum is the SHA3-256 of the component's Aleo source, as 32 bytes. The s Build tests along with the main program and dependencies. --checksums Print the program checksum and the checksum of each entry and view function - (the `Program::function_checksum` targets). + (the `std::prog::function_checksum` targets). --no-cache Don't use the dependency cache. --no-local diff --git a/documentation/code_snippets/cheatsheet/main/src/main.leo b/documentation/code_snippets/cheatsheet/main/src/main.leo index 50d2af59e99..4475835afbe 100644 --- a/documentation/code_snippets/cheatsheet/main/src/main.leo +++ b/documentation/code_snippets/cheatsheet/main/src/main.leo @@ -357,9 +357,9 @@ program cheatsheet.aleo { let root: field = 1field.square_root(); // Square root of the field/group element // Off-chain context expressions - let this: address = self.address; // Address of program - let caller: address = self.caller; // Address of function caller - let signer: address = self.signer; // Address of tx signer (origin) + let this: address = std::ctx::addr(); // Address of program + let caller: address = std::ctx::caller(); // Address of function caller + let signer: address = std::ctx::signer(); // Address of tx signer (origin) // Bit Serialization/Deserialization let bits: [bool; 90] = Serialize::to_bits(value); // Standard serialization (includes type metadata) @@ -373,11 +373,11 @@ program cheatsheet.aleo { return final { // On-chain context expressions - let height: u32 = block.height; // Height of current block - let now: i64 = block.timestamp; // Timestamp of current block - let checksum: [u8; 32] = self.checksum; // Checksum of a program - let edition: u16 = self.edition; // Edition of a program - let owner: address = self.program_owner; // Address that deployed a program + let height: u32 = std::ctx::block_height(); // Height of current block + let now: i64 = std::ctx::block_timestamp(); // Timestamp of current block + let checksum: [u8; 32] = std::ctx::checksum(); // Checksum of a program + let edition: u16 = std::ctx::edition(); // Edition of a program + let owner: address = std::ctx::program_owner(); // Address that deployed a program }; // ANCHOR_END: standard_operators } diff --git a/documentation/code_snippets/functions/offchain_annotation/program.json b/documentation/code_snippets/functions/offchain_annotation/program.json new file mode 100644 index 00000000000..d99299d6cd6 --- /dev/null +++ b/documentation/code_snippets/functions/offchain_annotation/program.json @@ -0,0 +1,8 @@ +{ + "program": "offchain_demo.aleo", + "version": "0.1.0", + "description": "", + "license": "MIT", + "dependencies": null, + "dev_dependencies": null +} diff --git a/documentation/code_snippets/functions/offchain_annotation/src/main.leo b/documentation/code_snippets/functions/offchain_annotation/src/main.leo new file mode 100644 index 00000000000..df665c18c83 --- /dev/null +++ b/documentation/code_snippets/functions/offchain_annotation/src/main.leo @@ -0,0 +1,19 @@ +// ANCHOR: snippet +// Thin wrapper around an off-chain-only intrinsic. The annotation +// propagates the restriction to every call site, so `who()` is also +// rejected inside `final fn`, `view fn`, or a `final {}` block. +@offchain +fn who() -> address { + return std::ctx::caller(); +} +// ANCHOR_END: snippet + +program offchain_demo.aleo { + // Allowed: an entry `fn` body is off-chain. + fn whoami() -> address { + return who(); + } + + @noupgrade + constructor() {} +} diff --git a/documentation/code_snippets/functions/transfer_final_fn/src/main.leo b/documentation/code_snippets/functions/transfer_final_fn/src/main.leo index 1af199d5a7a..a2cdde8b1f7 100644 --- a/documentation/code_snippets/functions/transfer_final_fn/src/main.leo +++ b/documentation/code_snippets/functions/transfer_final_fn/src/main.leo @@ -21,14 +21,14 @@ program transfer.aleo { amount, }; - let caller: address = self.caller; + let caller: address = std::ctx::caller(); return (new, final { decrement_balance(caller, amount); }); } fn burn(public amount: u64) -> Final { - let caller: address = self.caller; + let caller: address = std::ctx::caller(); return final { decrement_balance(caller, amount); }; diff --git a/documentation/code_snippets/functions/transfer_inline/src/main.leo b/documentation/code_snippets/functions/transfer_inline/src/main.leo index 578a9a0f90c..049b5103d0c 100644 --- a/documentation/code_snippets/functions/transfer_inline/src/main.leo +++ b/documentation/code_snippets/functions/transfer_inline/src/main.leo @@ -22,7 +22,7 @@ program transfer.aleo { amount, }; - let caller: address = self.caller; + let caller: address = std::ctx::caller(); // Return the receiver's record, then decrement the token amount of the caller publicly. return (new, final { // Decrements `account[sender]` by `amount`. diff --git a/documentation/code_snippets/functions/view_basic/src/main.leo b/documentation/code_snippets/functions/view_basic/src/main.leo index 4f20ee18179..2ef3480dc7f 100644 --- a/documentation/code_snippets/functions/view_basic/src/main.leo +++ b/documentation/code_snippets/functions/view_basic/src/main.leo @@ -3,14 +3,14 @@ program vault.aleo { mapping balances: address => u64; // A `view fn` is a read-only entry point. It can read mappings, storage, - // vectors, `block.height`, and `network.id`, but cannot write any state + // vectors, `std::ctx::block_height()`, and `std::ctx::network_id()`, but cannot write any state // or call other functions. view fn balance_of(account: address) -> u64 { return balances.get_or_use(account, 0u64); } fn deposit(amount: u64) -> Final { - let caller: address = self.caller; + let caller: address = std::ctx::caller(); return final { let current: u64 = Mapping::get_or_use(balances, caller, 0u64); Mapping::set(balances, caller, current + amount); diff --git a/documentation/code_snippets/interfaces/multi/src/main.leo b/documentation/code_snippets/interfaces/multi/src/main.leo index 669a26b8bc4..f2db1d9372f 100644 --- a/documentation/code_snippets/interfaces/multi/src/main.leo +++ b/documentation/code_snippets/interfaces/multi/src/main.leo @@ -23,7 +23,7 @@ program my_token.aleo : Transfer + Pausable { } fn pause() -> (bool, Final) { - let caller: address = self.caller; + let caller: address = std::ctx::caller(); return (true, final { Mapping::set(paused, caller, true); }); diff --git a/documentation/code_snippets/intrinsics/function_checksum/src/main.leo b/documentation/code_snippets/intrinsics/function_checksum/src/main.leo index e3c4817b0d9..114e0f8b781 100644 --- a/documentation/code_snippets/intrinsics/function_checksum/src/main.leo +++ b/documentation/code_snippets/intrinsics/function_checksum/src/main.leo @@ -11,9 +11,9 @@ program function_checksum_demo.aleo { fn audit() -> Final { return final { // Checksum of an entry function in the current program. - let f: [u8; 32] = Program::function_checksum(function_checksum_demo.aleo, 'audit'); + let f: [u8; 32] = std::prog::function_checksum::[function_checksum_demo.aleo, 'audit'](); // Checksum of a view function in the current program. - let v: [u8; 32] = Program::function_checksum(function_checksum_demo.aleo, 'balance_of'); + let v: [u8; 32] = std::prog::function_checksum::[function_checksum_demo.aleo, 'balance_of'](); assert_neq(f, v); }; } diff --git a/documentation/code_snippets/migration/transitions_to_fn/src/main.leo b/documentation/code_snippets/migration/transitions_to_fn/src/main.leo index c745ae7ba71..2263b189750 100644 --- a/documentation/code_snippets/migration/transitions_to_fn/src/main.leo +++ b/documentation/code_snippets/migration/transitions_to_fn/src/main.leo @@ -7,7 +7,7 @@ program test.aleo { } fn mint(public amount: u64) -> Token { - return Token { owner: self.caller, amount: amount }; + return Token { owner: std::ctx::caller(), amount: amount }; } @noupgrade diff --git a/documentation/code_snippets/operators/external_program_info/src/main.leo b/documentation/code_snippets/operators/external_program_info/src/main.leo index 0b8563e6102..119322b7dbb 100644 --- a/documentation/code_snippets/operators/external_program_info/src/main.leo +++ b/documentation/code_snippets/operators/external_program_info/src/main.leo @@ -4,15 +4,15 @@ program external_program_info.aleo { fn read_external_info() -> Final { return final { // ANCHOR: external_checksum - let ext_checksum: [u8; 32] = Program::checksum(credits.aleo); + let ext_checksum: [u8; 32] = std::prog::checksum::[credits.aleo](); // ANCHOR_END: external_checksum // ANCHOR: external_edition - let ext_edition: u16 = Program::edition(credits.aleo); + let ext_edition: u16 = std::prog::edition::[credits.aleo](); // ANCHOR_END: external_edition // ANCHOR: external_program_owner - let ext_owner: address = Program::program_owner(credits.aleo); + let ext_owner: address = std::prog::program_owner::[credits.aleo](); // ANCHOR_END: external_program_owner }; } diff --git a/documentation/code_snippets/operators/standard/src/main.leo b/documentation/code_snippets/operators/standard/src/main.leo index 21b46eb7625..5890fade8b1 100644 --- a/documentation/code_snippets/operators/standard/src/main.leo +++ b/documentation/code_snippets/operators/standard/src/main.leo @@ -323,32 +323,32 @@ program standard_ops_demo.aleo { // ANCHOR: self_address fn get_program_address() -> address { - return self.address; + return std::ctx::addr(); } // ANCHOR_END: self_address // ANCHOR: self_id fn get_program_id() -> address { - return self.id; + return std::ctx::id(); } // ANCHOR_END: self_id // ANCHOR: self_caller fn matches_caller(addr: address) -> bool { - return self.caller == addr; + return std::ctx::caller() == addr; } // ANCHOR_END: self_caller // ANCHOR: self_signer fn matches_signer(addr: address) -> bool { - return self.signer == addr; + return std::ctx::signer() == addr; } // ANCHOR_END: self_signer // ANCHOR: block_height fn matches_height(height: u32) -> Final { return final { - assert_eq(height, block.height); + assert_eq(height, std::ctx::block_height()); }; } // ANCHOR_END: block_height @@ -356,7 +356,7 @@ program standard_ops_demo.aleo { // ANCHOR: block_timestamp fn matches_timestamp(timestamp: i64) -> Final { return final { - assert_eq(timestamp, block.timestamp); + assert_eq(timestamp, std::ctx::block_timestamp()); }; } // ANCHOR_END: block_timestamp @@ -364,7 +364,7 @@ program standard_ops_demo.aleo { // ANCHOR: network_id fn matches_network(id: u16) -> Final { return final { - assert_eq(id, network.id); + assert_eq(id, std::ctx::network_id()); }; } // ANCHOR_END: network_id @@ -372,7 +372,7 @@ program standard_ops_demo.aleo { // ANCHOR: self_checksum fn matches_checksum(checksum: [u8; 32]) -> Final { return final { - assert_eq(self.checksum, checksum); + assert_eq(std::ctx::checksum(), checksum); }; } // ANCHOR_END: self_checksum @@ -380,7 +380,7 @@ program standard_ops_demo.aleo { // ANCHOR: self_edition fn matches_edition(edition: u16) -> Final { return final { - assert_eq(self.edition, edition); + assert_eq(std::ctx::edition(), edition); }; } // ANCHOR_END: self_edition @@ -388,7 +388,7 @@ program standard_ops_demo.aleo { // ANCHOR: self_program_owner fn matches_owner(owner: address) -> Final { return final { - assert_eq(self.program_owner, owner); + assert_eq(std::ctx::program_owner(), owner); }; } // ANCHOR_END: self_program_owner diff --git a/documentation/code_snippets/public_storage/demo/src/main.leo b/documentation/code_snippets/public_storage/demo/src/main.leo index 65cce36ec92..17aad2894fd 100644 --- a/documentation/code_snippets/public_storage/demo/src/main.leo +++ b/documentation/code_snippets/public_storage/demo/src/main.leo @@ -17,7 +17,7 @@ program public_state_demo.aleo { // ANCHOR: mapping_usage fn dubble() -> Final { - let addr: address = self.caller; + let addr: address = std::ctx::caller(); return final { let current_value: u64 = balance.get_or_use(addr, 0u64); balance.set(addr, current_value + 1u64); diff --git a/documentation/code_snippets/public_storage/storage_init/src/main.leo b/documentation/code_snippets/public_storage/storage_init/src/main.leo index 34ad8e2c3ab..e8a9bad0bac 100644 --- a/documentation/code_snippets/public_storage/storage_init/src/main.leo +++ b/documentation/code_snippets/public_storage/storage_init/src/main.leo @@ -12,7 +12,7 @@ program storage_init.aleo { constructor() { // Only initialize on the first deployment (edition 0). On upgrade // (edition > 0) the existing storage is preserved. - if self.edition == 0u16 { + if std::ctx::edition() == 0u16 { counter = 0u32; } } diff --git a/documentation/code_snippets/standard_library/src/main.leo b/documentation/code_snippets/standard_library/src/main.leo index 85fd2113f8e..3e75b6e1f48 100644 --- a/documentation/code_snippets/standard_library/src/main.leo +++ b/documentation/code_snippets/standard_library/src/main.leo @@ -115,6 +115,18 @@ program stdlib_demo.aleo { }; } + fn prog_demo() -> Final { + return final { + // ANCHOR: std_prog + // Other-program metadata; the target is a compile-time const generic. + let cs: [u8; 32] = std::prog::checksum::[stdlib_demo.aleo](); + let ed: u16 = std::prog::edition::[stdlib_demo.aleo](); + let ow: address = std::prog::program_owner::[stdlib_demo.aleo](); + let fc: [u8; 32] = std::prog::function_checksum::[stdlib_demo.aleo, 'prog_demo'](); + // ANCHOR_END: std_prog + }; + } + @noupgrade constructor() {} } diff --git a/documentation/code_snippets/testing/example_program/src/main.leo b/documentation/code_snippets/testing/example_program/src/main.leo index c8b81166ba0..9c0bd3fde07 100644 --- a/documentation/code_snippets/testing/example_program/src/main.leo +++ b/documentation/code_snippets/testing/example_program/src/main.leo @@ -18,7 +18,7 @@ program example_program.aleo { // ANCHOR: mint_record fn mint_record(x: field) -> Example { return Example { - owner: self.signer, + owner: std::ctx::signer(), x, }; } @@ -26,7 +26,7 @@ program example_program.aleo { // ANCHOR: pause fn pause() { - assert_eq(self.signer, ADMIN); + assert_eq(std::ctx::signer(), ADMIN); } // ANCHOR_END: pause diff --git a/documentation/code_snippets/testing/example_program/tests/test_example_program.leo b/documentation/code_snippets/testing/example_program/tests/test_example_program.leo index f4d661e79aa..385bdf86326 100644 --- a/documentation/code_snippets/testing/example_program/tests/test_example_program.leo +++ b/documentation/code_snippets/testing/example_program/tests/test_example_program.leo @@ -28,7 +28,7 @@ program test_example_program.aleo { // ANCHOR: test_with_private_key // Run this test as a specific account, not the default test account. - // `self.caller` and `self.signer` resolve to the address derived from + // `std::ctx::caller()` and `std::ctx::signer()` resolve to the address derived from // the supplied private key for the duration of this test. @test(private_key = "APrivateKey1zkpG9Af9z5Ha4ejVyMCqVFXRKknSm8L1ELEwcc4htk9YhVK") fn test_as_specific_account() { diff --git a/documentation/code_snippets/upgradability/timelock/src/main.leo b/documentation/code_snippets/upgradability/timelock/src/main.leo index d99e4358053..7b092c2b934 100644 --- a/documentation/code_snippets/upgradability/timelock/src/main.leo +++ b/documentation/code_snippets/upgradability/timelock/src/main.leo @@ -4,8 +4,8 @@ program timelock_example.aleo { @custom constructor() { // For upgrades (edition > 0), enforce a block height condition on when the constructor can be called successfully - if self.edition > 0u16 { - assert(block.height >= 1300u32); + if std::ctx::edition() > 0u16 { + assert(std::ctx::block_height() >= 1300u32); } } diff --git a/documentation/guides/program_upgradability.md b/documentation/guides/program_upgradability.md index fe13cda8b67..61c8153d272 100644 --- a/documentation/guides/program_upgradability.md +++ b/documentation/guides/program_upgradability.md @@ -57,16 +57,16 @@ There are two key properties of the `constructor` related to upgradability: ### Program Metadata Operands -Within a `constructor`, you can access on-chain metadata about the program using the `self` keyword. +Within a `constructor`, you can access on-chain metadata about the program through the [`std::ctx`](../language/standard_library.md#stdctx) module of the standard library. -| Operand | Leo Type | Description | -| -------------------- | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------- | -| `self.address` | `address` | The program's own account address. | -| `self.edition` | `u16` | The program's version number. Starts at `0` and is incremented by `1` for each upgrade. The edition is tracked automatically on the network. | -| `self.program_owner` | `address` | The address that submitted the deployment transaction. | -| `self.checksum` | `[u8, 32]` | The program's checksum, which is a unique identifier for the program's code. | +| Operand | Leo Type | Description | +| ----------------------------- | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------- | +| `std::ctx::addr()` | `address` | The program's own account address. | +| `std::ctx::edition()` | `u16` | The program's version number. Starts at `0` and is incremented by `1` for each upgrade. The edition is tracked automatically on the network. | +| `std::ctx::program_owner()` | `address` | The address that submitted the deployment transaction. | +| `std::ctx::checksum()` | `[u8, 32]` | The program's checksum, which is a unique identifier for the program's code. | -You may also refer to other program's metadata by qualifying the operand with the program name, like `Program::edition(credits.aleo)`, `Program::program_owner(foo.aleo)`. +You may also refer to another program's metadata through the [`std::prog`](../language/standard_library.md#stdprog) module — for example `std::prog::edition::[credits.aleo]()` or `std::prog::program_owner::[foo.aleo]()`. You will need to import the program in your Leo file to use this syntax. Note. Programs deployed before the upgradability feature (i.e. using Leo version < v3.1.0) do not have a `program_owner`. Attempting to access it will result in a runtime error. diff --git a/documentation/guides/testing.md b/documentation/guides/testing.md index 0b3e1ff57b6..661da5fe18c 100644 --- a/documentation/guides/testing.md +++ b/documentation/guides/testing.md @@ -71,7 +71,7 @@ The `@should_fail` annotation should be added after the `@test` annotation for t ### Testing as a Specific Account -By default, every `@test` function runs as the same fixed test account. The corresponding address is what [`self.caller`](../language/operators/standard_operators.md#selfcaller) and [`self.signer`](../language/operators/standard_operators.md#selfsigner) resolve to inside the test. The default key is: +By default, every `@test` function runs as the same fixed test account. The corresponding address is what [`std::ctx::caller()`](../language/standard_library.md#stdctx) and [`std::ctx::signer()`](../language/standard_library.md#stdctx) resolve to inside the test. The default key is: ```text APrivateKey1zkp8CZNn3yeCseEtxuVPbDCwSyhGW6yZKUYKfgXmcpoGPWH diff --git a/documentation/language/operators/standard_operators.md b/documentation/language/operators/standard_operators.md index 4b0db34d18a..ff76fef8331 100644 --- a/documentation/language/operators/standard_operators.md +++ b/documentation/language/operators/standard_operators.md @@ -20,8 +20,6 @@ toc_max_heading_level: 3 | [assert](#assert) | Assert boolean true | | [assert_eq](#assert_eq) | Assert equality | | [assert_neq](#assert_neq) | Assert non-equality | -| [block.height](#blockheight) | Fetch the latest block height | -| [block.timestamp](#blocktimestamp) | Fetch the latest block timestamp | | [Deserialize:from_bits::[TYPE]](#deserializefrom_bitstype) | Deserialize bits to a data type | | [div](#div) | Division | | [div_wrapped](#div_wrapped) | Wrapping division operation | @@ -41,7 +39,6 @@ toc_max_heading_level: 3 | [mul_wrapped](#mul_wrapped) | Wrapping multiplication | | [nand](#nand) | Negated conjunction | | [neg](#neg) | Additive inverse | -| [network.id](#networkid) | Fetch the network id | | [nor](#nor) | Negated disjunction | | [not](#not) | Logical negation | | [or](#or) | (Inclusive) disjunction | @@ -49,16 +46,6 @@ toc_max_heading_level: 3 | [pow_wrapped](#pow_wrapped) | Wrapping exponentiation | | [rem](#rem) | Remainder | | [rem_wrapped](#rem_wrapped) | Wrapping remainder | -| [Program::checksum](#programchecksum) | Checksum of another (imported) program | -| [Program::edition](#programedition) | Edition (version) of another (imported) program | -| [Program::program_owner](#programprogram_owner) | Deployer address of another (imported) program | -| [self.address](#selfaddress) | Address of the current program | -| [self.caller](#selfcaller) | Address of the calling user/program | -| [self.checksum](#selfchecksum) | Checksum of a program | -| [self.edition](#selfedition) | Version number of a program | -| [self.id](#selfid) | Address of the current program (alias of `self.address`) | -| [self.program_owner](#selfprogram_owner) | Address that submitted a program's deployment transaction | -| [self.signer](#selfsigner) | Address of the top-level calling user | | [Serialize::to_bits](#serializeto_bits) | Serialize data to bits | | [shl](#shl) | Shift left | | [shl_wrapped](#shl_wrapped) | Wrapping shift left | @@ -973,264 +960,7 @@ Checks if `first` is less than or equal to `second`, storing the result in `dest ## Context-dependent Expressions -### `block.height` - -```leo file=../../code_snippets/operators/standard/src/main.leo#block_height -``` - -The `block.height` operator is used to fetch the latest block height in a Leo program. It represents the number of -blocks in the chain. In the above example, `block.height` is used in a `final { }` block to fetch the latest block -height in a program. - -:::info - -- The `block.height` operator can only be used in on-chain context — a `final { }` block, a `final fn`, or a `constructor`. It is rejected in entry `fn` bodies, helper `fn`s, and constant initialisers, since chain state is only observable in the finalization context. -- The `block.height` operator doesn't take any parameters. - - ::: - -[Back to Top](#table-of-contents) - ---- - -### `block.timestamp` - -```leo file=../../code_snippets/operators/standard/src/main.leo#block_timestamp -``` - -The `block.timestamp` operator is used to fetch the UNIX timestamp of the latest block in a Leo program. In the above example, `block.timestamp` is used in a `final { }` block to fetch the latest block timestamp in a program. - -:::info - -- The `block.timestamp` operator can only be used in on-chain context — a `final { }` block, a `final fn`, or a `constructor`. It is rejected in entry `fn` bodies, helper `fn`s, and constant initialisers, since chain state is only observable in the finalization context. -- The `block.timestamp` operator doesn't take any parameters. - - ::: - -[Back to Top](#table-of-contents) - ---- - -### `network.id` - -```leo file=../../code_snippets/operators/standard/src/main.leo#network_id -``` - -The `network.id` operator is used to fetch the id of the network on which the program is running, as a `u16`. In the above example, `network.id` is used in a `final { }` block to fetch the current network id in a program. - -:::info - -- The `network.id` operator can only be used in on-chain context — a `final { }` block, a `final fn`, or a `constructor`. It is rejected in entry `fn` bodies, helper `fn`s, and constant initialisers, since chain state is only observable in the finalization context. -- The `network.id` operator doesn't take any parameters. - - ::: - -[Back to Top](#table-of-contents) - ---- - -### `self.address` - -```leo file=../../code_snippets/operators/standard/src/main.leo#self_address -``` - -The `self.address` operator returns the address of the program that calls it. While programs are identified by their name (`{PROGRAM_NAME}.aleo`), under the hood they have a corresponding Aleo address. - -:::info - -- The `self.address` operator may be used in any function context (entry `fn`, helper `fn`, `final fn`, `final { }` block, or `constructor`). -- The `self.address` operator doesn't take any parameters. - - ::: - -[Back to Top](#table-of-contents) - ---- - -### `self.caller` - -```leo file=../../code_snippets/operators/standard/src/main.leo#self_caller -``` - -The `self.caller` operator returns the address of the account/program that invoked the current entry function. Note that if the function was called as part of an external program, this operation will return the address of the program, NOT the address of the top-level user. - -:::info - -- The `self.caller` operator can only be used in **proof context** — inside an entry `fn` body or a helper `fn` body, but **not** inside a `final { }` block, a `final fn`, or a `constructor`. The notion of "the function's immediate caller" only exists in the proof context; finalization runs after the call has been validated. The compiler emits an error if `self.caller` is used in an on-chain context. -- The `self.caller` operator doesn't take any parameters. - - ::: - -[Back to Top](#table-of-contents) - ---- - -### `self.checksum` - -```leo file=../../code_snippets/operators/standard/src/main.leo#self_checksum -``` - -The `self.checksum` operator returns the current program's checksum, which is a unique identifier for the program's code. To reference another program's checksum, see [`Program::checksum`](#programchecksum). - -:::info - -- The `self.checksum` operator may be used in any function context (entry `fn`, helper `fn`, `final fn`, `final { }` block, or `constructor`). -- The `self.checksum` operator doesn't take any parameters. - - ::: - -[Back to Top](#table-of-contents) - ---- - -### `Program::checksum` - -```leo file=../../code_snippets/operators/external_program_info/src/main.leo#external_checksum -``` - -The `Program::checksum` operator returns the on-chain checksum of an **imported** program — the same value that program would observe with [`self.checksum`](#selfchecksum). The argument must be a program-ID literal of the form `name.aleo`, not a runtime address. - -#### Supported Types - -| Argument | Destination | -| -------------------- | ----------- | -| program ID literal | `[u8; 32]` | - -:::info - -- The `Program::checksum(other.aleo)` operator can only be used in on-chain context — a `final { }` block, a `final fn`, or a `constructor`. Using it elsewhere will result in a compilation error. -- The argument must be a program-ID literal (e.g. `credits.aleo`), not a variable typed as `address`. -- To reference another program's checksum, you will need to import that program first. - - ::: - -[Back to Top](#table-of-contents) - ---- - -### `self.edition` - -```leo file=../../code_snippets/operators/standard/src/main.leo#self_edition -``` - -The `self.edition` operator returns the current program's edition, which is the program's version number. A program's edition starts at zero and is incremented by one for each upgrade. The edition is tracked automatically on the network. To reference another program's edition, see [`Program::edition`](#programedition). - -:::info - -- The `self.edition` operator may be used in any function context (entry `fn`, helper `fn`, `final fn`, `final { }` block, or `constructor`). -- The `self.edition` operator doesn't take any parameters. - - ::: - -[Back to Top](#table-of-contents) - ---- - -### `Program::edition` - -```leo file=../../code_snippets/operators/external_program_info/src/main.leo#external_edition -``` - -The `Program::edition` operator returns the on-chain edition of an **imported** program — the same value that program would observe with [`self.edition`](#selfedition). Useful for guarding logic against specific upgrade versions of a dependency. The argument must be a program-ID literal. - -#### Supported Types - -| Argument | Destination | -| -------------------- | ----------- | -| program ID literal | `u16` | - -:::info - -- The `Program::edition(other.aleo)` operator can only be used in on-chain context — a `final { }` block, a `final fn`, or a `constructor`. Using it elsewhere will result in a compilation error. -- The argument must be a program-ID literal (e.g. `credits.aleo`), not a variable typed as `address`. -- To reference another program's edition, you will need to import that program first. - - ::: - -[Back to Top](#table-of-contents) - ---- - -### `self.id` - -```leo file=../../code_snippets/operators/standard/src/main.leo#self_id -``` - -The `self.id` operator returns the on-chain `address` of the program containing the call site. It is an alias of [`self.address`](#selfaddress) and lowers to the same Aleo instruction; the alternate spelling reads more naturally when comparing program identifiers. - -:::info - -- The `self.id` operator may be used in any function context (entry `fn`, helper `fn`, `final fn`, `final { }` block, or `constructor`). -- The `self.id` operator doesn't take any parameters. - - ::: - -[Back to Top](#table-of-contents) - ---- - -### `self.program_owner` - -```leo file=../../code_snippets/operators/standard/src/main.leo#self_program_owner -``` - -The `self.program_owner` operator returns the address that submitted the deployment transaction for the current program. To reference another program's owner, see [`Program::program_owner`](#programprogram_owner). - -:::info - -- The `self.program_owner` operator can only be used in on-chain context — a `final { }` block, a `final fn`, or a `constructor`. Using it elsewhere will result in a compilation error. -- The `self.program_owner` operator doesn't take any parameters. -- Programs deployed before the upgradability feature shipped (Leo `< v3.1.0`) do not have a `program_owner`. Reading `self.program_owner` on such a program halts at runtime. - - ::: - -[Back to Top](#table-of-contents) - ---- - -### `Program::program_owner` - -```leo file=../../code_snippets/operators/external_program_info/src/main.leo#external_program_owner -``` - -The `Program::program_owner` operator returns the address that submitted the deployment transaction for an **imported** program — the same value that program would observe with [`self.program_owner`](#selfprogram_owner). The argument must be a program-ID literal. - -#### Supported Types - -| Argument | Destination | -| -------------------- | ----------- | -| program ID literal | `address` | - -:::info - -- The `Program::program_owner(other.aleo)` operator can only be used in on-chain context — a `final { }` block, a `final fn`, or a `constructor`. Using it elsewhere will result in a compilation error. -- The argument must be a program-ID literal (e.g. `credits.aleo`), not a variable typed as `address`. -- To reference another program's owner, you will need to import that program first. -- If the target program was deployed before the upgradability feature shipped, this call halts at runtime. - - ::: - -[Back to Top](#table-of-contents) - ---- - -### `self.signer` - -```leo file=../../code_snippets/operators/standard/src/main.leo#self_signer -``` - -The `self.signer` operator returns the address of the account that invoked the top-level entry function. This will be the user account that signed the transaction. - -:::info - -- The `self.signer` operator can only be used in **proof context** — inside an entry `fn` body or a helper `fn` body, but **not** inside a `final { }` block, a `final fn`, or a `constructor`. Finalization values must be derived in proof context and passed forward as inputs. If you need the signer's address inside a `final { }` block, capture it in proof context first and pass it as an argument to the finalize call. -- The `self.signer` operator doesn't take any parameters. - - ::: - -[Back to Top](#table-of-contents) - ---- +Execution-context accessors — the immediate caller, the transaction signer, the program's own address, deployment metadata, and the current block / network — live in the [`std::ctx`](../standard_library.md#stdctx) module of the standard library. On-chain metadata for **other** (imported) programs (their checksum, edition, owner, and per-function checksum) lives in [`std::prog`](../standard_library.md#stdprog). ## Group/Field Specific Operators diff --git a/documentation/language/programs_in_practice/functions.md b/documentation/language/programs_in_practice/functions.md index 2dc77bca5f1..6cc2c1bc6bd 100644 --- a/documentation/language/programs_in_practice/functions.md +++ b/documentation/language/programs_in_practice/functions.md @@ -64,11 +64,11 @@ A `view fn` is a read-only entry point. It is declared inside a `program {}` blo ```leo file=../../code_snippets/functions/view_basic/src/main.leo#file showLineNumbers ``` -A `view fn` body sees the same on-chain context as a `final {}` block — it can read mappings, storage, vectors, `block.height`, and `network.id`. Beyond the `final {}` rules above, a view adds these restrictions: +A `view fn` body sees the same on-chain context as a `final {}` block — it can read mappings, storage, vectors, `std::ctx::block_height()`, and `std::ctx::network_id()`. Beyond the `final {}` rules above, a view adds these restrictions: - **Read-only.** All state writes are rejected — both singleton storage assignment (`counter = 5u64;`, `counter = none;`) and the mutating intrinsics `Mapping::set`, `Mapping::remove`, `Vector::set`, `Vector::push`, `Vector::pop`, `Vector::swap_remove`, `Vector::clear`. - **Leaf in the emitted bytecode.** A view may call a helper `fn` (its body is fully inlined into the view), but it cannot `call` another `view fn`, a `final fn`, or an entry point. This keeps the emitted Aleo `view` block free of `call` instructions, which snarkVM requires. Dynamic calls (the `dyn ...` form) are also rejected. -- No `block.timestamp`, `Snark::verify`, `Snark::verify_batch`, or `program_owner` — these are available in `final {}` but not when a node evaluates a view off-consensus. +- No `std::ctx::block_timestamp()`, `Snark::verify`, `Snark::verify_batch`, or `std::ctx::program_owner()` — these are available in `final {}` but not when a node evaluates a view off-consensus. - Returns plaintext only (no records); cannot be combined with `final`. ### Calling Views from On-chain Code @@ -105,10 +105,10 @@ Helper functions also support **const generics**: ```leo file=../../code_snippets/functions/const_generic/src/main.leo showLineNumbers ``` -Acceptable types for const generic parameters include integer types, `bool`, `scalar`, `group`, `field`, and `address`. +Acceptable types for const generic parameters include integer types, `bool`, `scalar`, `group`, `field`, `address`, and `identifier`. :::note -Const generic parameters are only valid on inlinable helper `fn` functions. They are not permitted on entry point functions inside a `program {}` block, `final fn` functions, functions annotated with `@no_inline`, or function signatures declared inside an `interface`. +Const generic parameters are only valid on functions that are inlined at every call site. They are not permitted on entry point functions inside a `program {}` block, functions annotated with `@no_inline`, or function signatures declared inside an `interface`. `final fn`s are always inlined into their `final {}` callsite, so they may declare const generic parameters. ::: ### The `@no_inline` Annotation @@ -140,6 +140,26 @@ The annotation has no effect on entry `fn` declarations either — the entry-poi The compiler accepts `@inline` as a recognized annotation name, but **no compiler pass acts on it** — it is a silent no-op carried over from earlier Leo versions, where `inline` was a function-modifier keyword rather than an annotation (see [Migrating from Leo 3.5 to 4.0](../../guides/migration_3_5_to_4_0.md#inline-becomes-fn)). The default inlining behaviour described above is the same whether or not `@inline` is present, so prefer to leave it out of new code. +### The `@offchain` Annotation + +Some values — most notably the immediate caller and the transaction signer — are only meaningful while a transition is being authorized off-chain. They have no analogue inside `final {}`, a `final fn`, a `constructor`, or a `view fn`, all of which execute after the transition is already accepted on-chain. + +`@offchain` marks a `fn` as carrying that restriction. The compiler rejects every call to an `@offchain`-annotated function from an on-chain context. Because the check fires at the call site, the restriction transparently propagates through wrappers: if your helper calls something `@offchain`, you can apply `@offchain` to your helper and any code that calls *it* will be checked in turn. + +The standard library uses this on [`std::ctx::caller()`](../standard_library.md#stdctx) and [`std::ctx::signer()`](../standard_library.md#stdctx). Apply it to your own wrappers when you want the same compile-time enforcement: + +```leo file=../../code_snippets/functions/offchain_annotation/src/main.leo#snippet +``` + +#### Where `@offchain` callees are rejected + +- inside a `final {}` async block, +- inside a `final fn` body, +- inside a `constructor` body (the synthesized finalize block), +- inside a `view fn` body. + +They are allowed only inside entry `fn` and helper `fn` bodies. + ## Function Call Rules - An entry `fn` can call: helper `fn`s, `final fn`s, and external entry `fn`s. Local entry `fn`s and `view fn`s (outside a `final {}` block) are rejected. diff --git a/documentation/language/programs_in_practice/intrinsics.md b/documentation/language/programs_in_practice/intrinsics.md index 228a238ce10..8241e5c05a0 100644 --- a/documentation/language/programs_in_practice/intrinsics.md +++ b/documentation/language/programs_in_practice/intrinsics.md @@ -150,27 +150,3 @@ Reads a value from a mapping belonging to another program, determined at runtime ```leo file=../../code_snippets/intrinsics/dynamic_get_or_use/src/main.leo showLineNumbers ``` - ---- - -## `Program::function_checksum` - -Returns the 32-byte checksum (`[u8; 32]`) of a single named program component — an **entry function** or a **view function**. On-chain logic (a `final {}` block, a `final fn`, or a `constructor`) can use it to assert that a specific function's compiled bytecode matches an expected value, for example to pin a critical function across a program upgrade. - -Available from consensus version V16. - -### Syntax - -```text -Program::function_checksum(, '') -``` - -- `` — a program ID literal (e.g. `token.aleo`): the current program's own ID for a local function, or an imported program's ID for an external one. -- `''` — an identifier literal naming the target component. It must resolve to an **entry function** or a **view function** of that program. Closures (uninlined helpers), `final fn` helpers, and names that do not resolve are rejected at compile time. - -### Example - -```leo file=../../code_snippets/intrinsics/function_checksum/src/main.leo#file -``` - -To checksum a function in another program, pass that program's ID — the program must be imported. diff --git a/documentation/language/standard_library.md b/documentation/language/standard_library.md index d1f03df13bc..2b20b464d23 100644 --- a/documentation/language/standard_library.md +++ b/documentation/language/standard_library.md @@ -40,6 +40,7 @@ entries. - [`std::serialize`](#stdserialize) — bit-level encoding and decoding - [`std::grp`](#stdgrp) — group generators and coordinates - [`std::ctx`](#stdctx) — execution context +- [`std::prog`](#stdprog) — on-chain metadata for imported programs --- @@ -329,3 +330,23 @@ of the entire transaction. | `block_height()` | `u32` | Height of the block containing the current transaction. | | `block_timestamp()`| `i64` | Unix timestamp (seconds) of the block containing the current transaction. | | `network_id()` | `u16` | Numeric identifier of the network (mainnet, testnet, canary, etc). | + +--- + +## `std::prog` + +On-chain metadata accessors for **imported** programs. Each function takes the program identifier as a **const generic argument**, so the target program is fixed at compile time — the AVM has no instruction for choosing a target dynamically. Use these to gate logic on a dependency program's deployed version, checksum, or owner. + +All functions in this module are `final fn`s, so they can only be called from a `final { ... }` block, a `final fn`, or a `constructor`. + +```leo file=../code_snippets/standard_library/src/main.leo#std_prog +``` + +| Function | Returns | Description | +| ------------------------------------------------ | ----------- | ---------------------------------------------------------------------------------------------------- | +| `checksum::[PROG]()` | `[u8; 32]` | 32-byte deployment checksum of the program `PROG`; changes only when the program is upgraded. | +| `edition::[PROG]()` | `u16` | Deployment edition of the program `PROG`; `0` is the initial deployment, each upgrade increments it. | +| `program_owner::[PROG]()` | `address` | Address that owns `PROG` (typically the deployer); halts at runtime for pre-upgradability programs. | +| `function_checksum::[PROG, FN_NAME]()` | `[u8; 32]` | 32-byte checksum of function `FN_NAME` inside `PROG`. Useful for pinning a dependency's function. | + +The `PROG` argument must be a program-ID literal (`foo.aleo`); `FN_NAME` must be an identifier literal (`'bar'`). diff --git a/documentation/language/structure.md b/documentation/language/structure.md index 6bbf1cdc6ef..2b0b83ebe62 100644 --- a/documentation/language/structure.md +++ b/documentation/language/structure.md @@ -34,12 +34,12 @@ Two properties set a `constructor` apart from an ordinary function: ```leo file=../code_snippets/upgradability/noupgrade/src/main.leo#file ``` -Inside a `constructor`, you can read on-chain program metadata through `self` — namely `self.address`, `self.edition`, `self.program_owner`, and `self.checksum`. A `@custom` constructor typically branches on `self.edition` to apply different rules at first deployment (`edition == 0`) versus later upgrades: +Inside a `constructor`, you can read on-chain program metadata through the [`std::ctx`](./standard_library.md#stdctx) module — namely `std::ctx::addr()`, `std::ctx::edition()`, `std::ctx::program_owner()`, and `std::ctx::checksum()`. A `@custom` constructor typically branches on `std::ctx::edition()` to apply different rules at first deployment (`edition == 0`) versus later upgrades: ```leo file=../code_snippets/upgradability/timelock/src/main.leo#file ``` -For the annotation argument grammar, the type and meaning of each `self.*` operand, and worked patterns for every upgrade mode, see the [Upgrading Programs guide](../guides/program_upgradability.md). +For the annotation argument grammar, the meaning of each `std::ctx::*()` accessor, and worked patterns for every upgrade mode, see the [Upgrading Programs guide](../guides/program_upgradability.md). ### Constant diff --git a/examples b/examples index b28b5b1e1d8..03554ec37f2 160000 --- a/examples +++ b/examples @@ -1 +1 @@ -Subproject commit b28b5b1e1d8b0c62131aae95526a331b53873553 +Subproject commit 03554ec37f22f76470a488abb326b323dc90be35 diff --git a/tests/expectations/cli/test_ast_snapshots_library/contents/expected_snapshots/TypeChecking.ast b/tests/expectations/cli/test_ast_snapshots_library/contents/expected_snapshots/TypeChecking.ast index b61db284b66..849c7ba0de4 100644 --- a/tests/expectations/cli/test_ast_snapshots_library/contents/expected_snapshots/TypeChecking.ast +++ b/tests/expectations/cli/test_ast_snapshots_library/contents/expected_snapshots/TypeChecking.ast @@ -17832,13 +17832,16 @@ module ctx { fn addr() -> address { return _self_address(); } + @offchain + @_caller_annotation fn caller() -> address { return _self_caller(); } + @offchain fn signer() -> address { return _self_signer(); } - final fn id() -> address { + fn id() -> address { return _self_id(); } final fn checksum() -> [u8; 32] { @@ -17861,6 +17864,26 @@ module ctx { } } +module prog { + @_program_id_arg + final fn checksum::[PROG: address]() -> [u8; 32] { + return _program_checksum(PROG); + } + @_program_id_arg + final fn edition::[PROG: address]() -> u16 { + return _program_edition(PROG); + } + @_program_id_arg + final fn program_owner::[PROG: address]() -> address { + return _program_owner(PROG); + } + @_program_id_arg + @_callable_function_arg + final fn function_checksum::[PROG: address, FN_NAME: identifier]() -> [u8; 32] { + return _function_checksum(PROG, FN_NAME); + } +} + } library ast_library { diff --git a/tests/expectations/cli/test_ast_snapshots_library/contents/expected_snapshots/TypeChecking.json b/tests/expectations/cli/test_ast_snapshots_library/contents/expected_snapshots/TypeChecking.json index 630399f47c5..ad88c9ac5f1 100644 --- a/tests/expectations/cli/test_ast_snapshots_library/contents/expected_snapshots/TypeChecking.json +++ b/tests/expectations/cli/test_ast_snapshots_library/contents/expected_snapshots/TypeChecking.json @@ -12,14 +12,14 @@ { "place": { "name": "UNIT", - "id": 84210 + "id": 84289 }, "type_": { "Integer": "U32" }, "value": { "Literal": { - "id": 84211, + "id": 84290, "variant": { "Integer": [ "U32", @@ -28,7 +28,7 @@ } } }, - "id": 84209 + "id": 84288 } ] ], @@ -41,20 +41,20 @@ "variant": "Fn", "identifier": { "name": "increment", - "id": 84213 + "id": 84292 }, "const_parameters": [], "input": [ { "identifier": { "name": "x", - "id": 84215 + "id": 84294 }, "mode": "None", "type_": { "Integer": "U32" }, - "id": 84214 + "id": 84293 } ], "output": [ @@ -63,7 +63,7 @@ "type_": { "Integer": "U32" }, - "id": 84216 + "id": 84295 } ], "output_type": { @@ -81,12 +81,12 @@ "qualifier": [], "identifier": { "name": "x", - "id": 84221 + "id": 84300 }, "target": { "Local": "x" }, - "id": 84222 + "id": 84301 } }, "right": { @@ -95,7 +95,7 @@ "qualifier": [], "identifier": { "name": "UNIT", - "id": 84224 + "id": 84303 }, "target": { "Global": { @@ -106,20 +106,20 @@ ] } }, - "id": 84225 + "id": 84304 } }, "op": "Add", - "id": 84220 + "id": 84299 } }, - "id": 84219 + "id": 84298 } } ], - "id": 84217 + "id": 84296 }, - "id": 84212 + "id": 84291 } ] ], @@ -136,31 +136,31 @@ "variant": "Fn", "identifier": { "name": "scale", - "id": 84193 + "id": 84272 }, "const_parameters": [], "input": [ { "identifier": { "name": "x", - "id": 84195 + "id": 84274 }, "mode": "None", "type_": { "Integer": "U32" }, - "id": 84194 + "id": 84273 }, { "identifier": { "name": "factor", - "id": 84197 + "id": 84276 }, "mode": "None", "type_": { "Integer": "U32" }, - "id": 84196 + "id": 84275 } ], "output": [ @@ -169,7 +169,7 @@ "type_": { "Integer": "U32" }, - "id": 84198 + "id": 84277 } ], "output_type": { @@ -187,12 +187,12 @@ "qualifier": [], "identifier": { "name": "x", - "id": 84203 + "id": 84282 }, "target": { "Local": "x" }, - "id": 84204 + "id": 84283 } }, "right": { @@ -201,25 +201,25 @@ "qualifier": [], "identifier": { "name": "factor", - "id": 84206 + "id": 84285 }, "target": { "Local": "factor" }, - "id": 84207 + "id": 84286 } }, "op": "Mul", - "id": 84202 + "id": 84281 } }, - "id": 84201 + "id": 84280 } } ], - "id": 84199 + "id": 84278 }, - "id": 84192 + "id": 84271 } ] ], @@ -430726,11 +430726,28 @@ [ "caller", { - "annotations": [], + "annotations": [ + { + "identifier": { + "name": "offchain", + "id": 84112 + }, + "map": {}, + "id": 84111 + }, + { + "identifier": { + "name": "_caller_annotation", + "id": 84114 + }, + "map": {}, + "id": 84113 + } + ], "variant": "Fn", "identifier": { "name": "caller", - "id": 84111 + "id": 84115 }, "const_parameters": [], "input": [], @@ -430738,7 +430755,7 @@ { "mode": "None", "type_": "Address", - "id": 84112 + "id": 84116 } ], "output_type": "Address", @@ -430753,14 +430770,14 @@ "input_types": [], "return_types": [], "arguments": [], - "id": 84116 + "id": 84120 } }, - "id": 84115 + "id": 84119 } } ], - "id": 84113 + "id": 84117 }, "id": 84110 } @@ -430768,11 +430785,20 @@ [ "signer", { - "annotations": [], + "annotations": [ + { + "identifier": { + "name": "offchain", + "id": 84125 + }, + "map": {}, + "id": 84124 + } + ], "variant": "Fn", "identifier": { "name": "signer", - "id": 84120 + "id": 84126 }, "const_parameters": [], "input": [], @@ -430780,7 +430806,7 @@ { "mode": "None", "type_": "Address", - "id": 84121 + "id": 84127 } ], "output_type": "Address", @@ -430795,26 +430821,26 @@ "input_types": [], "return_types": [], "arguments": [], - "id": 84125 + "id": 84131 } }, - "id": 84124 + "id": 84130 } } ], - "id": 84122 + "id": 84128 }, - "id": 84119 + "id": 84123 } ], [ "id", { "annotations": [], - "variant": "FinalFn", + "variant": "Fn", "identifier": { "name": "id", - "id": 84129 + "id": 84135 }, "const_parameters": [], "input": [], @@ -430822,7 +430848,7 @@ { "mode": "None", "type_": "Address", - "id": 84130 + "id": 84136 } ], "output_type": "Address", @@ -430837,16 +430863,16 @@ "input_types": [], "return_types": [], "arguments": [], - "id": 84134 + "id": 84140 } }, - "id": 84133 + "id": 84139 } } ], - "id": 84131 + "id": 84137 }, - "id": 84128 + "id": 84134 } ], [ @@ -430856,7 +430882,7 @@ "variant": "FinalFn", "identifier": { "name": "checksum", - "id": 84138 + "id": 84144 }, "const_parameters": [], "input": [], @@ -430870,7 +430896,7 @@ }, "length": { "Literal": { - "id": 84139, + "id": 84145, "variant": { "Unsuffixed": "32" } @@ -430878,7 +430904,7 @@ } } }, - "id": 84140 + "id": 84146 } ], "output_type": { @@ -430888,7 +430914,7 @@ }, "length": { "Literal": { - "id": 84139, + "id": 84145, "variant": { "Unsuffixed": "32" } @@ -430907,16 +430933,16 @@ "input_types": [], "return_types": [], "arguments": [], - "id": 84144 + "id": 84150 } }, - "id": 84143 + "id": 84149 } } ], - "id": 84141 + "id": 84147 }, - "id": 84137 + "id": 84143 } ], [ @@ -430926,7 +430952,7 @@ "variant": "FinalFn", "identifier": { "name": "edition", - "id": 84148 + "id": 84154 }, "const_parameters": [], "input": [], @@ -430936,7 +430962,7 @@ "type_": { "Integer": "U16" }, - "id": 84149 + "id": 84155 } ], "output_type": { @@ -430953,16 +430979,16 @@ "input_types": [], "return_types": [], "arguments": [], - "id": 84153 + "id": 84159 } }, - "id": 84152 + "id": 84158 } } ], - "id": 84150 + "id": 84156 }, - "id": 84147 + "id": 84153 } ], [ @@ -430972,7 +430998,7 @@ "variant": "FinalFn", "identifier": { "name": "program_owner", - "id": 84157 + "id": 84163 }, "const_parameters": [], "input": [], @@ -430980,7 +431006,7 @@ { "mode": "None", "type_": "Address", - "id": 84158 + "id": 84164 } ], "output_type": "Address", @@ -430995,16 +431021,16 @@ "input_types": [], "return_types": [], "arguments": [], - "id": 84162 + "id": 84168 } }, - "id": 84161 + "id": 84167 } } ], - "id": 84159 + "id": 84165 }, - "id": 84156 + "id": 84162 } ], [ @@ -431014,7 +431040,7 @@ "variant": "FinalFn", "identifier": { "name": "block_height", - "id": 84166 + "id": 84172 }, "const_parameters": [], "input": [], @@ -431024,7 +431050,7 @@ "type_": { "Integer": "U32" }, - "id": 84167 + "id": 84173 } ], "output_type": { @@ -431041,16 +431067,16 @@ "input_types": [], "return_types": [], "arguments": [], - "id": 84171 + "id": 84177 } }, - "id": 84170 + "id": 84176 } } ], - "id": 84168 + "id": 84174 }, - "id": 84165 + "id": 84171 } ], [ @@ -431060,7 +431086,7 @@ "variant": "FinalFn", "identifier": { "name": "block_timestamp", - "id": 84175 + "id": 84181 }, "const_parameters": [], "input": [], @@ -431070,7 +431096,7 @@ "type_": { "Integer": "I64" }, - "id": 84176 + "id": 84182 } ], "output_type": { @@ -431087,16 +431113,16 @@ "input_types": [], "return_types": [], "arguments": [], - "id": 84180 + "id": 84186 } }, - "id": 84179 + "id": 84185 } } ], - "id": 84177 + "id": 84183 }, - "id": 84174 + "id": 84180 } ], [ @@ -431106,7 +431132,7 @@ "variant": "FinalFn", "identifier": { "name": "network_id", - "id": 84184 + "id": 84190 }, "const_parameters": [], "input": [], @@ -431116,7 +431142,7 @@ "type_": { "Integer": "U16" }, - "id": 84185 + "id": 84191 } ], "output_type": { @@ -431133,16 +431159,417 @@ "input_types": [], "return_types": [], "arguments": [], - "id": 84189 + "id": 84195 + } + }, + "id": 84194 + } + } + ], + "id": 84192 + }, + "id": 84189 + } + ] + ], + "interfaces": [] + }, + "prog": { + "unit_name": "std", + "path": [ + "prog" + ], + "consts": [], + "composites": [], + "functions": [ + [ + "checksum", + { + "annotations": [ + { + "identifier": { + "name": "_program_id_arg", + "id": 84200 + }, + "map": {}, + "id": 84199 + } + ], + "variant": "FinalFn", + "identifier": { + "name": "checksum", + "id": 84201 + }, + "const_parameters": [ + { + "identifier": { + "name": "PROG", + "id": 84203 + }, + "type_": "Address", + "id": 84202 + } + ], + "input": [], + "output": [ + { + "mode": "None", + "type_": { + "Array": { + "element_type": { + "Integer": "U8" + }, + "length": { + "Literal": { + "id": 84204, + "variant": { + "Unsuffixed": "32" + } + } + } + } + }, + "id": 84205 + } + ], + "output_type": { + "Array": { + "element_type": { + "Integer": "U8" + }, + "length": { + "Literal": { + "id": 84204, + "variant": { + "Unsuffixed": "32" + } + } + } + } + }, + "block": { + "statements": [ + { + "Return": { + "expression": { + "Intrinsic": { + "name": "_program_checksum", + "type_parameters": [], + "input_types": [], + "return_types": [], + "arguments": [ + { + "Path": { + "user_program": null, + "qualifier": [], + "identifier": { + "name": "PROG", + "id": 84212 + }, + "target": { + "Local": "PROG" + }, + "id": 84213 + } + } + ], + "id": 84209 + } + }, + "id": 84208 + } + } + ], + "id": 84206 + }, + "id": 84198 + } + ], + [ + "edition", + { + "annotations": [ + { + "identifier": { + "name": "_program_id_arg", + "id": 84217 + }, + "map": {}, + "id": 84216 + } + ], + "variant": "FinalFn", + "identifier": { + "name": "edition", + "id": 84218 + }, + "const_parameters": [ + { + "identifier": { + "name": "PROG", + "id": 84220 + }, + "type_": "Address", + "id": 84219 + } + ], + "input": [], + "output": [ + { + "mode": "None", + "type_": { + "Integer": "U16" + }, + "id": 84221 + } + ], + "output_type": { + "Integer": "U16" + }, + "block": { + "statements": [ + { + "Return": { + "expression": { + "Intrinsic": { + "name": "_program_edition", + "type_parameters": [], + "input_types": [], + "return_types": [], + "arguments": [ + { + "Path": { + "user_program": null, + "qualifier": [], + "identifier": { + "name": "PROG", + "id": 84228 + }, + "target": { + "Local": "PROG" + }, + "id": 84229 + } + } + ], + "id": 84225 + } + }, + "id": 84224 + } + } + ], + "id": 84222 + }, + "id": 84215 + } + ], + [ + "program_owner", + { + "annotations": [ + { + "identifier": { + "name": "_program_id_arg", + "id": 84233 + }, + "map": {}, + "id": 84232 + } + ], + "variant": "FinalFn", + "identifier": { + "name": "program_owner", + "id": 84234 + }, + "const_parameters": [ + { + "identifier": { + "name": "PROG", + "id": 84236 + }, + "type_": "Address", + "id": 84235 + } + ], + "input": [], + "output": [ + { + "mode": "None", + "type_": "Address", + "id": 84237 + } + ], + "output_type": "Address", + "block": { + "statements": [ + { + "Return": { + "expression": { + "Intrinsic": { + "name": "_program_owner", + "type_parameters": [], + "input_types": [], + "return_types": [], + "arguments": [ + { + "Path": { + "user_program": null, + "qualifier": [], + "identifier": { + "name": "PROG", + "id": 84244 + }, + "target": { + "Local": "PROG" + }, + "id": 84245 + } + } + ], + "id": 84241 + } + }, + "id": 84240 + } + } + ], + "id": 84238 + }, + "id": 84231 + } + ], + [ + "function_checksum", + { + "annotations": [ + { + "identifier": { + "name": "_program_id_arg", + "id": 84249 + }, + "map": {}, + "id": 84248 + }, + { + "identifier": { + "name": "_callable_function_arg", + "id": 84251 + }, + "map": {}, + "id": 84250 + } + ], + "variant": "FinalFn", + "identifier": { + "name": "function_checksum", + "id": 84252 + }, + "const_parameters": [ + { + "identifier": { + "name": "PROG", + "id": 84254 + }, + "type_": "Address", + "id": 84253 + }, + { + "identifier": { + "name": "FN_NAME", + "id": 84256 + }, + "type_": "Identifier", + "id": 84255 + } + ], + "input": [], + "output": [ + { + "mode": "None", + "type_": { + "Array": { + "element_type": { + "Integer": "U8" + }, + "length": { + "Literal": { + "id": 84257, + "variant": { + "Unsuffixed": "32" + } + } + } + } + }, + "id": 84258 + } + ], + "output_type": { + "Array": { + "element_type": { + "Integer": "U8" + }, + "length": { + "Literal": { + "id": 84257, + "variant": { + "Unsuffixed": "32" + } + } + } + } + }, + "block": { + "statements": [ + { + "Return": { + "expression": { + "Intrinsic": { + "name": "_function_checksum", + "type_parameters": [], + "input_types": [], + "return_types": [], + "arguments": [ + { + "Path": { + "user_program": null, + "qualifier": [], + "identifier": { + "name": "PROG", + "id": 84265 + }, + "target": { + "Local": "PROG" + }, + "id": 84266 + } + }, + { + "Path": { + "user_program": null, + "qualifier": [], + "identifier": { + "name": "FN_NAME", + "id": 84268 + }, + "target": { + "Local": "FN_NAME" + }, + "id": 84269 + } + } + ], + "id": 84262 } }, - "id": 84188 + "id": 84261 } } ], - "id": 84186 + "id": 84259 }, - "id": 84183 + "id": 84247 } ] ], diff --git a/tests/expectations/cli/test_ast_snapshots_library/contents/expected_snapshots/initial.json b/tests/expectations/cli/test_ast_snapshots_library/contents/expected_snapshots/initial.json index 4684805a331..f05a8364122 100644 --- a/tests/expectations/cli/test_ast_snapshots_library/contents/expected_snapshots/initial.json +++ b/tests/expectations/cli/test_ast_snapshots_library/contents/expected_snapshots/initial.json @@ -12,14 +12,14 @@ { "place": { "name": "UNIT", - "id": 84210 + "id": 84289 }, "type_": { "Integer": "U32" }, "value": { "Literal": { - "id": 84211, + "id": 84290, "variant": { "Integer": [ "U32", @@ -28,7 +28,7 @@ } } }, - "id": 84209 + "id": 84288 } ] ], @@ -41,20 +41,20 @@ "variant": "Fn", "identifier": { "name": "increment", - "id": 84213 + "id": 84292 }, "const_parameters": [], "input": [ { "identifier": { "name": "x", - "id": 84215 + "id": 84294 }, "mode": "None", "type_": { "Integer": "U32" }, - "id": 84214 + "id": 84293 } ], "output": [ @@ -63,7 +63,7 @@ "type_": { "Integer": "U32" }, - "id": 84216 + "id": 84295 } ], "output_type": { @@ -81,10 +81,10 @@ "qualifier": [], "identifier": { "name": "x", - "id": 84221 + "id": 84300 }, "target": "Unresolved", - "id": 84222 + "id": 84301 } }, "right": { @@ -93,23 +93,23 @@ "qualifier": [], "identifier": { "name": "UNIT", - "id": 84224 + "id": 84303 }, "target": "Unresolved", - "id": 84225 + "id": 84304 } }, "op": "Add", - "id": 84220 + "id": 84299 } }, - "id": 84219 + "id": 84298 } } ], - "id": 84217 + "id": 84296 }, - "id": 84212 + "id": 84291 } ] ], @@ -126,31 +126,31 @@ "variant": "Fn", "identifier": { "name": "scale", - "id": 84193 + "id": 84272 }, "const_parameters": [], "input": [ { "identifier": { "name": "x", - "id": 84195 + "id": 84274 }, "mode": "None", "type_": { "Integer": "U32" }, - "id": 84194 + "id": 84273 }, { "identifier": { "name": "factor", - "id": 84197 + "id": 84276 }, "mode": "None", "type_": { "Integer": "U32" }, - "id": 84196 + "id": 84275 } ], "output": [ @@ -159,7 +159,7 @@ "type_": { "Integer": "U32" }, - "id": 84198 + "id": 84277 } ], "output_type": { @@ -177,10 +177,10 @@ "qualifier": [], "identifier": { "name": "x", - "id": 84203 + "id": 84282 }, "target": "Unresolved", - "id": 84204 + "id": 84283 } }, "right": { @@ -189,23 +189,23 @@ "qualifier": [], "identifier": { "name": "factor", - "id": 84206 + "id": 84285 }, "target": "Unresolved", - "id": 84207 + "id": 84286 } }, "op": "Mul", - "id": 84202 + "id": 84281 } }, - "id": 84201 + "id": 84280 } } ], - "id": 84199 + "id": 84278 }, - "id": 84192 + "id": 84271 } ] ], diff --git a/tests/expectations/cli/test_ast_snapshots_program/contents/expected_snapshots/Flattening.ast b/tests/expectations/cli/test_ast_snapshots_program/contents/expected_snapshots/Flattening.ast index 89e24bb9dfd..dec77e88af9 100644 --- a/tests/expectations/cli/test_ast_snapshots_program/contents/expected_snapshots/Flattening.ast +++ b/tests/expectations/cli/test_ast_snapshots_program/contents/expected_snapshots/Flattening.ast @@ -80,6 +80,9 @@ module grp { module ctx { } +module prog { +} + } program ast_program.aleo { diff --git a/tests/expectations/cli/test_ast_snapshots_program/contents/expected_snapshots/Flattening.json b/tests/expectations/cli/test_ast_snapshots_program/contents/expected_snapshots/Flattening.json index 5ebd2efbddf..b09c5efa2cc 100644 --- a/tests/expectations/cli/test_ast_snapshots_program/contents/expected_snapshots/Flattening.json +++ b/tests/expectations/cli/test_ast_snapshots_program/contents/expected_snapshots/Flattening.json @@ -297,6 +297,16 @@ "composites": [], "functions": [], "interfaces": [] + }, + "prog": { + "unit_name": "std", + "path": [ + "prog" + ], + "consts": [], + "composites": [], + "functions": [], + "interfaces": [] } }, "consts": [], @@ -316,11 +326,11 @@ "program_id": { "name": { "name": "ast_program", - "id": 84192 + "id": 84271 }, "network": { "name": "aleo", - "id": 84193 + "id": 84272 } }, "parents": [], @@ -336,31 +346,31 @@ "variant": "EntryPoint", "identifier": { "name": "main", - "id": 84195 + "id": 84274 }, "const_parameters": [], "input": [ { "identifier": { "name": "a$$0", - "id": 84223 + "id": 84302 }, "mode": "Public", "type_": { "Integer": "U32" }, - "id": 84196 + "id": 84275 }, { "identifier": { "name": "b$$1", - "id": 84224 + "id": 84303 }, "mode": "None", "type_": { "Integer": "U32" }, - "id": 84198 + "id": 84277 } ], "output": [ @@ -369,7 +379,7 @@ "type_": { "Integer": "U32" }, - "id": 84200 + "id": 84279 } ], "output_type": { @@ -382,7 +392,7 @@ "place": { "Single": { "name": "c$#2", - "id": 84204 + "id": 84283 } }, "type_": null, @@ -394,12 +404,12 @@ "qualifier": [], "identifier": { "name": "a$$0", - "id": 84207 + "id": 84286 }, "target": { "Local": "a$$0" }, - "id": 84207 + "id": 84286 } }, "right": { @@ -408,19 +418,19 @@ "qualifier": [], "identifier": { "name": "b$$1", - "id": 84210 + "id": 84289 }, "target": { "Local": "b$$1" }, - "id": 84210 + "id": 84289 } }, "op": "Add", - "id": 84205 + "id": 84284 } }, - "id": 84228 + "id": 84307 } }, { @@ -437,21 +447,21 @@ "qualifier": [], "identifier": { "name": "c$#2", - "id": 84215 + "id": 84294 }, "target": { "Local": "c$#2" }, - "id": 84215 + "id": 84294 } }, - "id": 84230 + "id": 84309 } } ], - "id": 84229 + "id": 84308 }, - "id": 84194 + "id": 84273 } ] ], @@ -461,10 +471,10 @@ { "identifier": { "name": "noupgrade", - "id": 84219 + "id": 84298 }, "map": {}, - "id": 84218 + "id": 84297 } ], "block": { @@ -473,16 +483,16 @@ "Return": { "expression": { "Unit": { - "id": 84232 + "id": 84311 } }, - "id": 84233 + "id": 84312 } } ], - "id": 84231 + "id": 84310 }, - "id": 84217 + "id": 84296 } } } diff --git a/tests/expectations/cli/test_ast_snapshots_program/contents/expected_snapshots/TypeChecking.ast b/tests/expectations/cli/test_ast_snapshots_program/contents/expected_snapshots/TypeChecking.ast index eaec89d07fc..415febf98b6 100644 --- a/tests/expectations/cli/test_ast_snapshots_program/contents/expected_snapshots/TypeChecking.ast +++ b/tests/expectations/cli/test_ast_snapshots_program/contents/expected_snapshots/TypeChecking.ast @@ -17832,13 +17832,16 @@ module ctx { fn addr() -> address { return _self_address(); } + @offchain + @_caller_annotation fn caller() -> address { return _self_caller(); } + @offchain fn signer() -> address { return _self_signer(); } - final fn id() -> address { + fn id() -> address { return _self_id(); } final fn checksum() -> [u8; 32] { @@ -17861,6 +17864,26 @@ module ctx { } } +module prog { + @_program_id_arg + final fn checksum::[PROG: address]() -> [u8; 32] { + return _program_checksum(PROG); + } + @_program_id_arg + final fn edition::[PROG: address]() -> u16 { + return _program_edition(PROG); + } + @_program_id_arg + final fn program_owner::[PROG: address]() -> address { + return _program_owner(PROG); + } + @_program_id_arg + @_callable_function_arg + final fn function_checksum::[PROG: address, FN_NAME: identifier]() -> [u8; 32] { + return _function_checksum(PROG, FN_NAME); + } +} + } program ast_program.aleo { diff --git a/tests/expectations/cli/test_ast_snapshots_program/contents/expected_snapshots/TypeChecking.json b/tests/expectations/cli/test_ast_snapshots_program/contents/expected_snapshots/TypeChecking.json index 76b1ebb9b83..7245db5ed4a 100644 --- a/tests/expectations/cli/test_ast_snapshots_program/contents/expected_snapshots/TypeChecking.json +++ b/tests/expectations/cli/test_ast_snapshots_program/contents/expected_snapshots/TypeChecking.json @@ -430503,11 +430503,28 @@ [ "caller", { - "annotations": [], + "annotations": [ + { + "identifier": { + "name": "offchain", + "id": 84112 + }, + "map": {}, + "id": 84111 + }, + { + "identifier": { + "name": "_caller_annotation", + "id": 84114 + }, + "map": {}, + "id": 84113 + } + ], "variant": "Fn", "identifier": { "name": "caller", - "id": 84111 + "id": 84115 }, "const_parameters": [], "input": [], @@ -430515,7 +430532,7 @@ { "mode": "None", "type_": "Address", - "id": 84112 + "id": 84116 } ], "output_type": "Address", @@ -430530,14 +430547,14 @@ "input_types": [], "return_types": [], "arguments": [], - "id": 84116 + "id": 84120 } }, - "id": 84115 + "id": 84119 } } ], - "id": 84113 + "id": 84117 }, "id": 84110 } @@ -430545,11 +430562,20 @@ [ "signer", { - "annotations": [], + "annotations": [ + { + "identifier": { + "name": "offchain", + "id": 84125 + }, + "map": {}, + "id": 84124 + } + ], "variant": "Fn", "identifier": { "name": "signer", - "id": 84120 + "id": 84126 }, "const_parameters": [], "input": [], @@ -430557,7 +430583,7 @@ { "mode": "None", "type_": "Address", - "id": 84121 + "id": 84127 } ], "output_type": "Address", @@ -430572,26 +430598,26 @@ "input_types": [], "return_types": [], "arguments": [], - "id": 84125 + "id": 84131 } }, - "id": 84124 + "id": 84130 } } ], - "id": 84122 + "id": 84128 }, - "id": 84119 + "id": 84123 } ], [ "id", { "annotations": [], - "variant": "FinalFn", + "variant": "Fn", "identifier": { "name": "id", - "id": 84129 + "id": 84135 }, "const_parameters": [], "input": [], @@ -430599,7 +430625,7 @@ { "mode": "None", "type_": "Address", - "id": 84130 + "id": 84136 } ], "output_type": "Address", @@ -430614,16 +430640,16 @@ "input_types": [], "return_types": [], "arguments": [], - "id": 84134 + "id": 84140 } }, - "id": 84133 + "id": 84139 } } ], - "id": 84131 + "id": 84137 }, - "id": 84128 + "id": 84134 } ], [ @@ -430633,7 +430659,7 @@ "variant": "FinalFn", "identifier": { "name": "checksum", - "id": 84138 + "id": 84144 }, "const_parameters": [], "input": [], @@ -430647,7 +430673,7 @@ }, "length": { "Literal": { - "id": 84139, + "id": 84145, "variant": { "Unsuffixed": "32" } @@ -430655,7 +430681,7 @@ } } }, - "id": 84140 + "id": 84146 } ], "output_type": { @@ -430665,7 +430691,7 @@ }, "length": { "Literal": { - "id": 84139, + "id": 84145, "variant": { "Unsuffixed": "32" } @@ -430684,16 +430710,16 @@ "input_types": [], "return_types": [], "arguments": [], - "id": 84144 + "id": 84150 } }, - "id": 84143 + "id": 84149 } } ], - "id": 84141 + "id": 84147 }, - "id": 84137 + "id": 84143 } ], [ @@ -430703,7 +430729,7 @@ "variant": "FinalFn", "identifier": { "name": "edition", - "id": 84148 + "id": 84154 }, "const_parameters": [], "input": [], @@ -430713,7 +430739,7 @@ "type_": { "Integer": "U16" }, - "id": 84149 + "id": 84155 } ], "output_type": { @@ -430730,16 +430756,16 @@ "input_types": [], "return_types": [], "arguments": [], - "id": 84153 + "id": 84159 } }, - "id": 84152 + "id": 84158 } } ], - "id": 84150 + "id": 84156 }, - "id": 84147 + "id": 84153 } ], [ @@ -430749,7 +430775,7 @@ "variant": "FinalFn", "identifier": { "name": "program_owner", - "id": 84157 + "id": 84163 }, "const_parameters": [], "input": [], @@ -430757,7 +430783,7 @@ { "mode": "None", "type_": "Address", - "id": 84158 + "id": 84164 } ], "output_type": "Address", @@ -430772,16 +430798,16 @@ "input_types": [], "return_types": [], "arguments": [], - "id": 84162 + "id": 84168 } }, - "id": 84161 + "id": 84167 } } ], - "id": 84159 + "id": 84165 }, - "id": 84156 + "id": 84162 } ], [ @@ -430791,7 +430817,7 @@ "variant": "FinalFn", "identifier": { "name": "block_height", - "id": 84166 + "id": 84172 }, "const_parameters": [], "input": [], @@ -430801,7 +430827,7 @@ "type_": { "Integer": "U32" }, - "id": 84167 + "id": 84173 } ], "output_type": { @@ -430818,16 +430844,16 @@ "input_types": [], "return_types": [], "arguments": [], - "id": 84171 + "id": 84177 } }, - "id": 84170 + "id": 84176 } } ], - "id": 84168 + "id": 84174 }, - "id": 84165 + "id": 84171 } ], [ @@ -430837,7 +430863,7 @@ "variant": "FinalFn", "identifier": { "name": "block_timestamp", - "id": 84175 + "id": 84181 }, "const_parameters": [], "input": [], @@ -430847,7 +430873,7 @@ "type_": { "Integer": "I64" }, - "id": 84176 + "id": 84182 } ], "output_type": { @@ -430864,16 +430890,16 @@ "input_types": [], "return_types": [], "arguments": [], - "id": 84180 + "id": 84186 } }, - "id": 84179 + "id": 84185 } } ], - "id": 84177 + "id": 84183 }, - "id": 84174 + "id": 84180 } ], [ @@ -430883,7 +430909,7 @@ "variant": "FinalFn", "identifier": { "name": "network_id", - "id": 84184 + "id": 84190 }, "const_parameters": [], "input": [], @@ -430893,7 +430919,7 @@ "type_": { "Integer": "U16" }, - "id": 84185 + "id": 84191 } ], "output_type": { @@ -430910,16 +430936,417 @@ "input_types": [], "return_types": [], "arguments": [], - "id": 84189 + "id": 84195 } }, - "id": 84188 + "id": 84194 } } ], - "id": 84186 + "id": 84192 }, - "id": 84183 + "id": 84189 + } + ] + ], + "interfaces": [] + }, + "prog": { + "unit_name": "std", + "path": [ + "prog" + ], + "consts": [], + "composites": [], + "functions": [ + [ + "checksum", + { + "annotations": [ + { + "identifier": { + "name": "_program_id_arg", + "id": 84200 + }, + "map": {}, + "id": 84199 + } + ], + "variant": "FinalFn", + "identifier": { + "name": "checksum", + "id": 84201 + }, + "const_parameters": [ + { + "identifier": { + "name": "PROG", + "id": 84203 + }, + "type_": "Address", + "id": 84202 + } + ], + "input": [], + "output": [ + { + "mode": "None", + "type_": { + "Array": { + "element_type": { + "Integer": "U8" + }, + "length": { + "Literal": { + "id": 84204, + "variant": { + "Unsuffixed": "32" + } + } + } + } + }, + "id": 84205 + } + ], + "output_type": { + "Array": { + "element_type": { + "Integer": "U8" + }, + "length": { + "Literal": { + "id": 84204, + "variant": { + "Unsuffixed": "32" + } + } + } + } + }, + "block": { + "statements": [ + { + "Return": { + "expression": { + "Intrinsic": { + "name": "_program_checksum", + "type_parameters": [], + "input_types": [], + "return_types": [], + "arguments": [ + { + "Path": { + "user_program": null, + "qualifier": [], + "identifier": { + "name": "PROG", + "id": 84212 + }, + "target": { + "Local": "PROG" + }, + "id": 84213 + } + } + ], + "id": 84209 + } + }, + "id": 84208 + } + } + ], + "id": 84206 + }, + "id": 84198 + } + ], + [ + "edition", + { + "annotations": [ + { + "identifier": { + "name": "_program_id_arg", + "id": 84217 + }, + "map": {}, + "id": 84216 + } + ], + "variant": "FinalFn", + "identifier": { + "name": "edition", + "id": 84218 + }, + "const_parameters": [ + { + "identifier": { + "name": "PROG", + "id": 84220 + }, + "type_": "Address", + "id": 84219 + } + ], + "input": [], + "output": [ + { + "mode": "None", + "type_": { + "Integer": "U16" + }, + "id": 84221 + } + ], + "output_type": { + "Integer": "U16" + }, + "block": { + "statements": [ + { + "Return": { + "expression": { + "Intrinsic": { + "name": "_program_edition", + "type_parameters": [], + "input_types": [], + "return_types": [], + "arguments": [ + { + "Path": { + "user_program": null, + "qualifier": [], + "identifier": { + "name": "PROG", + "id": 84228 + }, + "target": { + "Local": "PROG" + }, + "id": 84229 + } + } + ], + "id": 84225 + } + }, + "id": 84224 + } + } + ], + "id": 84222 + }, + "id": 84215 + } + ], + [ + "program_owner", + { + "annotations": [ + { + "identifier": { + "name": "_program_id_arg", + "id": 84233 + }, + "map": {}, + "id": 84232 + } + ], + "variant": "FinalFn", + "identifier": { + "name": "program_owner", + "id": 84234 + }, + "const_parameters": [ + { + "identifier": { + "name": "PROG", + "id": 84236 + }, + "type_": "Address", + "id": 84235 + } + ], + "input": [], + "output": [ + { + "mode": "None", + "type_": "Address", + "id": 84237 + } + ], + "output_type": "Address", + "block": { + "statements": [ + { + "Return": { + "expression": { + "Intrinsic": { + "name": "_program_owner", + "type_parameters": [], + "input_types": [], + "return_types": [], + "arguments": [ + { + "Path": { + "user_program": null, + "qualifier": [], + "identifier": { + "name": "PROG", + "id": 84244 + }, + "target": { + "Local": "PROG" + }, + "id": 84245 + } + } + ], + "id": 84241 + } + }, + "id": 84240 + } + } + ], + "id": 84238 + }, + "id": 84231 + } + ], + [ + "function_checksum", + { + "annotations": [ + { + "identifier": { + "name": "_program_id_arg", + "id": 84249 + }, + "map": {}, + "id": 84248 + }, + { + "identifier": { + "name": "_callable_function_arg", + "id": 84251 + }, + "map": {}, + "id": 84250 + } + ], + "variant": "FinalFn", + "identifier": { + "name": "function_checksum", + "id": 84252 + }, + "const_parameters": [ + { + "identifier": { + "name": "PROG", + "id": 84254 + }, + "type_": "Address", + "id": 84253 + }, + { + "identifier": { + "name": "FN_NAME", + "id": 84256 + }, + "type_": "Identifier", + "id": 84255 + } + ], + "input": [], + "output": [ + { + "mode": "None", + "type_": { + "Array": { + "element_type": { + "Integer": "U8" + }, + "length": { + "Literal": { + "id": 84257, + "variant": { + "Unsuffixed": "32" + } + } + } + } + }, + "id": 84258 + } + ], + "output_type": { + "Array": { + "element_type": { + "Integer": "U8" + }, + "length": { + "Literal": { + "id": 84257, + "variant": { + "Unsuffixed": "32" + } + } + } + } + }, + "block": { + "statements": [ + { + "Return": { + "expression": { + "Intrinsic": { + "name": "_function_checksum", + "type_parameters": [], + "input_types": [], + "return_types": [], + "arguments": [ + { + "Path": { + "user_program": null, + "qualifier": [], + "identifier": { + "name": "PROG", + "id": 84265 + }, + "target": { + "Local": "PROG" + }, + "id": 84266 + } + }, + { + "Path": { + "user_program": null, + "qualifier": [], + "identifier": { + "name": "FN_NAME", + "id": 84268 + }, + "target": { + "Local": "FN_NAME" + }, + "id": 84269 + } + } + ], + "id": 84262 + } + }, + "id": 84261 + } + } + ], + "id": 84259 + }, + "id": 84247 } ] ], @@ -430943,11 +431370,11 @@ "program_id": { "name": { "name": "ast_program", - "id": 84192 + "id": 84271 }, "network": { "name": "aleo", - "id": 84193 + "id": 84272 } }, "parents": [], @@ -430963,31 +431390,31 @@ "variant": "EntryPoint", "identifier": { "name": "main", - "id": 84195 + "id": 84274 }, "const_parameters": [], "input": [ { "identifier": { "name": "a", - "id": 84197 + "id": 84276 }, "mode": "Public", "type_": { "Integer": "U32" }, - "id": 84196 + "id": 84275 }, { "identifier": { "name": "b", - "id": 84199 + "id": 84278 }, "mode": "None", "type_": { "Integer": "U32" }, - "id": 84198 + "id": 84277 } ], "output": [ @@ -430996,7 +431423,7 @@ "type_": { "Integer": "U32" }, - "id": 84200 + "id": 84279 } ], "output_type": { @@ -431009,7 +431436,7 @@ "place": { "Single": { "name": "c", - "id": 84204 + "id": 84283 } }, "type_": { @@ -431023,12 +431450,12 @@ "qualifier": [], "identifier": { "name": "a", - "id": 84206 + "id": 84285 }, "target": { "Local": "a" }, - "id": 84207 + "id": 84286 } }, "right": { @@ -431037,19 +431464,19 @@ "qualifier": [], "identifier": { "name": "b", - "id": 84209 + "id": 84288 }, "target": { "Local": "b" }, - "id": 84210 + "id": 84289 } }, "op": "Add", - "id": 84205 + "id": 84284 } }, - "id": 84203 + "id": 84282 } }, { @@ -431060,21 +431487,21 @@ "qualifier": [], "identifier": { "name": "c", - "id": 84214 + "id": 84293 }, "target": { "Local": "c" }, - "id": 84215 + "id": 84294 } }, - "id": 84213 + "id": 84292 } } ], - "id": 84201 + "id": 84280 }, - "id": 84194 + "id": 84273 } ] ], @@ -431084,17 +431511,17 @@ { "identifier": { "name": "noupgrade", - "id": 84219 + "id": 84298 }, "map": {}, - "id": 84218 + "id": 84297 } ], "block": { "statements": [], - "id": 84220 + "id": 84299 }, - "id": 84217 + "id": 84296 } } } diff --git a/tests/expectations/cli/test_ast_snapshots_program/contents/expected_snapshots/initial.json b/tests/expectations/cli/test_ast_snapshots_program/contents/expected_snapshots/initial.json index 586e2eb1aad..2827456643b 100644 --- a/tests/expectations/cli/test_ast_snapshots_program/contents/expected_snapshots/initial.json +++ b/tests/expectations/cli/test_ast_snapshots_program/contents/expected_snapshots/initial.json @@ -7,11 +7,11 @@ "program_id": { "name": { "name": "ast_program", - "id": 84192 + "id": 84271 }, "network": { "name": "aleo", - "id": 84193 + "id": 84272 } }, "parents": [], @@ -27,31 +27,31 @@ "variant": "EntryPoint", "identifier": { "name": "main", - "id": 84195 + "id": 84274 }, "const_parameters": [], "input": [ { "identifier": { "name": "a", - "id": 84197 + "id": 84276 }, "mode": "Public", "type_": { "Integer": "U32" }, - "id": 84196 + "id": 84275 }, { "identifier": { "name": "b", - "id": 84199 + "id": 84278 }, "mode": "None", "type_": { "Integer": "U32" }, - "id": 84198 + "id": 84277 } ], "output": [ @@ -60,7 +60,7 @@ "type_": { "Integer": "U32" }, - "id": 84200 + "id": 84279 } ], "output_type": { @@ -73,7 +73,7 @@ "place": { "Single": { "name": "c", - "id": 84204 + "id": 84283 } }, "type_": { @@ -87,10 +87,10 @@ "qualifier": [], "identifier": { "name": "a", - "id": 84206 + "id": 84285 }, "target": "Unresolved", - "id": 84207 + "id": 84286 } }, "right": { @@ -99,17 +99,17 @@ "qualifier": [], "identifier": { "name": "b", - "id": 84209 + "id": 84288 }, "target": "Unresolved", - "id": 84210 + "id": 84289 } }, "op": "Add", - "id": 84205 + "id": 84284 } }, - "id": 84203 + "id": 84282 } }, { @@ -120,19 +120,19 @@ "qualifier": [], "identifier": { "name": "c", - "id": 84214 + "id": 84293 }, "target": "Unresolved", - "id": 84215 + "id": 84294 } }, - "id": 84213 + "id": 84292 } } ], - "id": 84201 + "id": 84280 }, - "id": 84194 + "id": 84273 } ] ], @@ -142,17 +142,17 @@ { "identifier": { "name": "noupgrade", - "id": 84219 + "id": 84298 }, "map": {}, - "id": 84218 + "id": 84297 } ], "block": { "statements": [], - "id": 84220 + "id": 84299 }, - "id": 84217 + "id": 84296 } } } diff --git a/tests/expectations/cli/test_devnode_persistent_storage/contents/src/main.leo b/tests/expectations/cli/test_devnode_persistent_storage/contents/src/main.leo index b2cf741c370..5ac943d0357 100644 --- a/tests/expectations/cli/test_devnode_persistent_storage/contents/src/main.leo +++ b/tests/expectations/cli/test_devnode_persistent_storage/contents/src/main.leo @@ -3,7 +3,7 @@ program persistent_counter.aleo { mapping counts: address => u64; fn increment() -> Final { - let caller: address = self.caller; + let caller: address = std::ctx::caller(); return final { let current: u64 = counts.get_or_use(caller, 0u64); counts.set(caller, current + 1u64); diff --git a/tests/expectations/compiler/address/self_address_fail.out b/tests/expectations/compiler/address/self_address_fail.out index a76cc8626dd..02e81d179fa 100644 --- a/tests/expectations/compiler/address/self_address_fail.out +++ b/tests/expectations/compiler/address/self_address_fail.out @@ -1,9 +1,9 @@ -[ETYC0372117] Error: expected type `bool`, but type `address` was found +[ETYC0372003] Error: expected type `bool`, found type `address` ╭─[ compiler-test:3:16 ] │ - 3 │ return self.address; + 3 │ return std::ctx::addr(); │ - │ Help: Change the expression to produce type `bool`. + │ Help: Change the expression to produce a `bool`, or cast it with `as bool` if a conversion exists. ───╯ [ETYC0372117] Error: expected type `bool`, but type `address` was found ╭─[ compiler-test:8:16 ] diff --git a/tests/expectations/compiler/async_blocks/invalid_call_to_async_func.out b/tests/expectations/compiler/async_blocks/invalid_call_to_async_func.out index 7441c66ce64..f132acc6cb1 100644 --- a/tests/expectations/compiler/async_blocks/invalid_call_to_async_func.out +++ b/tests/expectations/compiler/async_blocks/invalid_call_to_async_func.out @@ -1,3 +1,10 @@ +[ETYC0372042] Error: only regular `fn`s can be called from a transition body outside a `final {}` block + ╭─[ compiler-test:3:16 ] + │ + 3 │ return bar(); + │ + │ Help: Move the callee out of the `program` block, or call a regular `fn` from this site instead. +───╯ [ETYC0372003] Error: expected type `Final`, found type `()` ╭─[ compiler-test:3:16 ] │ diff --git a/tests/expectations/compiler/async_blocks/invalid_expr_in_async_block_fail.out b/tests/expectations/compiler/async_blocks/invalid_expr_in_async_block_fail.out index c2a8337b4a8..70929ddd0d8 100644 --- a/tests/expectations/compiler/async_blocks/invalid_expr_in_async_block_fail.out +++ b/tests/expectations/compiler/async_blocks/invalid_expr_in_async_block_fail.out @@ -1,14 +1,14 @@ -[ETYC0372147] Error: `self.signer` cannot be used directly inside a `final` block +[ETYC0372147] Error: `std::ctx::signer()` cannot be used directly inside a `final` block ╭─[ compiler-test:4:21 ] │ - 4 │ let s = self.signer; + 4 │ let s = std::ctx::signer(); │ - │ Help: Bind `self.signer` to a variable before the `final` block: `let val = self.signer;`. + │ Help: Bind `std::ctx::signer()` to a variable before the `final` block: `let val = std::ctx::signer();`. ───╯ -[ETYC0372147] Error: `self.caller` cannot be used directly inside a `final` block +[ETYC0372147] Error: `std::ctx::caller()` cannot be used directly inside a `final` block ╭─[ compiler-test:5:21 ] │ - 5 │ let c = self.caller; + 5 │ let c = std::ctx::caller(); │ - │ Help: Bind `self.caller` to a variable before the `final` block: `let val = self.caller;`. + │ Help: Bind `std::ctx::caller()` to a variable before the `final` block: `let val = std::ctx::caller();`. ───╯ diff --git a/tests/expectations/compiler/async_blocks/self_in_async_block_fail.out b/tests/expectations/compiler/async_blocks/self_in_async_block_fail.out index 9f623988a01..828c0ad50a0 100644 --- a/tests/expectations/compiler/async_blocks/self_in_async_block_fail.out +++ b/tests/expectations/compiler/async_blocks/self_in_async_block_fail.out @@ -1,14 +1,14 @@ -[ETYC0372147] Error: `self.caller` cannot be used directly inside a `final` block +[ETYC0372147] Error: `std::ctx::caller()` cannot be used directly inside a `final` block ╭─[ compiler-test:4:21 ] │ - 4 │ let c = self.caller; + 4 │ let c = std::ctx::caller(); │ - │ Help: Bind `self.caller` to a variable before the `final` block: `let val = self.caller;`. + │ Help: Bind `std::ctx::caller()` to a variable before the `final` block: `let val = std::ctx::caller();`. ───╯ -[ETYC0372147] Error: `self.signer` cannot be used directly inside a `final` block +[ETYC0372147] Error: `std::ctx::signer()` cannot be used directly inside a `final` block ╭─[ compiler-test:5:21 ] │ - 5 │ let s = self.signer; + 5 │ let s = std::ctx::signer(); │ - │ Help: Bind `self.signer` to a variable before the `final` block: `let val = self.signer;`. + │ Help: Bind `std::ctx::signer()` to a variable before the `final` block: `let val = std::ctx::signer();`. ───╯ diff --git a/tests/expectations/compiler/bugs/b28611.out b/tests/expectations/compiler/bugs/b28611.out index 3fa585dea35..1a374d09d0b 100644 --- a/tests/expectations/compiler/bugs/b28611.out +++ b/tests/expectations/compiler/bugs/b28611.out @@ -1,14 +1,14 @@ [ETYC0372117] Error: expected anything but a mapping, tuple, or unit, but type `(u32, u32)` was found - ╭─[ compiler-test:7:47 ] + ╭─[ compiler-test:7:54 ] │ - 7 │ let b: bool = sig.verify(self.caller, t); + 7 │ let b: bool = sig.verify(std::ctx::caller(), t); │ │ Help: Change the expression to produce anything but a mapping, tuple, or unit. ───╯ [ETYC0372117] Error: expected anything but a mapping, tuple, or unit, but type `(u8 => u8)` was found - ╭─[ compiler-test:8:47 ] + ╭─[ compiler-test:8:54 ] │ - 8 │ let c: bool = sig.verify(self.caller, m); + 8 │ let c: bool = sig.verify(std::ctx::caller(), m); │ │ Help: Change the expression to produce anything but a mapping, tuple, or unit. ───╯ diff --git a/tests/expectations/compiler/bugs/b28614.out b/tests/expectations/compiler/bugs/b28614.out index 0ec70ac0d4d..dc2ada9bb0a 100644 --- a/tests/expectations/compiler/bugs/b28614.out +++ b/tests/expectations/compiler/bugs/b28614.out @@ -1,28 +1,28 @@ -[ETYC0372117] Error: expected type `u32`, but type `address` was found +[ETYC0372003] Error: expected type `u32`, found type `address` ╭─[ compiler-test:3:22 ] │ - 3 │ let x: u32 = self.caller; + 3 │ let x: u32 = std::ctx::caller(); │ - │ Help: Change the expression to produce type `u32`. + │ Help: Change the expression to produce a `u32`, or cast it with `as u32` if a conversion exists. ───╯ -[ETYC0372117] Error: expected type `u8`, but type `address` was found +[ETYC0372003] Error: expected type `u8`, found type `address` ╭─[ compiler-test:4:21 ] │ - 4 │ let y: u8 = self.caller; + 4 │ let y: u8 = std::ctx::caller(); │ - │ Help: Change the expression to produce type `u8`. + │ Help: Change the expression to produce a `u8`, or cast it with `as u8` if a conversion exists. ───╯ -[ETYC0372117] Error: expected type `u8`, but type `address` was found +[ETYC0372003] Error: expected type `u8`, found type `address` ╭─[ compiler-test:7:13 ] │ - 7 │ z = self.caller; + 7 │ z = std::ctx::caller(); │ - │ Help: Change the expression to produce type `u8`. + │ Help: Change the expression to produce a `u8`, or cast it with `as u8` if a conversion exists. ───╯ -[ETYC0372117] Error: expected type `field`, but type `address` was found +[ETYC0372003] Error: expected type `field`, found type `address` ╭─[ compiler-test:10:13 ] │ - 10 │ w = self.signer; + 10 │ w = std::ctx::signer(); │ - │ Help: Change the expression to produce type `field`. + │ Help: Change the expression to produce a `field`, or cast it with `as field` if a conversion exists. ────╯ diff --git a/tests/expectations/compiler/const_generics/const_generics_invalid_context_fail.out b/tests/expectations/compiler/const_generics/const_generics_invalid_context_fail.out index 1f9029d21e8..183e3753869 100644 --- a/tests/expectations/compiler/const_generics/const_generics_invalid_context_fail.out +++ b/tests/expectations/compiler/const_generics/const_generics_invalid_context_fail.out @@ -6,16 +6,16 @@ │ Help: Remove the const generic parameters from this entry point functions. ───╯ [ETYC0372143] Error: entry point functions cannot have generic const parameters - ╭─[ compiler-test:19:8 ] + ╭─[ compiler-test:17:8 ] │ - 19 │ fn bar1::[N: u32]() {} + 17 │ fn bar1::[N: u32]() {} │ │ Help: Remove the const generic parameters from this entry point functions. ────╯ [ETYC0372143] Error: entry point functions cannot have generic const parameters - ╭─[ compiler-test:21:8 ] + ╭─[ compiler-test:19:8 ] │ - 21 │ fn bar2::[N: u32]() -> Final { + 19 │ fn bar2::[N: u32]() -> Final { │ │ Help: Remove the const generic parameters from this entry point functions. ────╯ @@ -26,10 +26,3 @@ │ │ Help: Remove the const generic parameters from this functions annotated with `@no_inline`. ───╯ -[ETYC0372143] Error: `final fn` functions cannot have generic const parameters - ╭─[ compiler-test:10:10 ] - │ - 10 │ final fn foo2::[N: u32](x: u32) {} - │ - │ Help: Remove the const generic parameters from this `final fn` functions. -────╯ diff --git a/tests/expectations/compiler/const_generics/final_fn_const_generics.out b/tests/expectations/compiler/const_generics/final_fn_const_generics.out new file mode 100644 index 00000000000..db071b4f5bf --- /dev/null +++ b/tests/expectations/compiler/const_generics/final_fn_const_generics.out @@ -0,0 +1,11 @@ +program test.aleo; + +function run: + async run into r0; + output r0 as test.aleo/run.future; + +finalize run: + assert.eq 15u32 15u32; + +constructor: + assert.eq edition 0u16; diff --git a/tests/expectations/compiler/constants/block_height_type_fail.out b/tests/expectations/compiler/constants/block_height_type_fail.out index dba970ddb9a..0e60490a9f0 100644 --- a/tests/expectations/compiler/constants/block_height_type_fail.out +++ b/tests/expectations/compiler/constants/block_height_type_fail.out @@ -1,7 +1,7 @@ -[ETYC0372117] Error: expected type `u64`, but type `u32` was found +[ETYC0372003] Error: expected type `u64`, found type `u32` ╭─[ compiler-test:2:18 ] │ - 2 │ let x: u64 = block.height; + 2 │ let x: u64 = std::ctx::block_height(); │ - │ Help: Change the expression to produce type `u64`. + │ Help: Change the expression to produce a `u64`, or cast it with `as u64` if a conversion exists. ───╯ diff --git a/tests/expectations/compiler/constants/block_timestamp_type_fail.out b/tests/expectations/compiler/constants/block_timestamp_type_fail.out index 78c94309db6..93e9ff5b137 100644 --- a/tests/expectations/compiler/constants/block_timestamp_type_fail.out +++ b/tests/expectations/compiler/constants/block_timestamp_type_fail.out @@ -1,7 +1,7 @@ -[ETYC0372117] Error: expected type `u32`, but type `i64` was found +[ETYC0372003] Error: expected type `u32`, found type `i64` ╭─[ compiler-test:2:18 ] │ - 2 │ let x: u32 = block.timestamp; + 2 │ let x: u32 = std::ctx::block_timestamp(); │ - │ Help: Change the expression to produce type `u32`. + │ Help: Change the expression to produce a `u32`, or cast it with `as u32` if a conversion exists. ───╯ diff --git a/tests/expectations/compiler/dynamic_dispatch/dynamic_get_wrong_arg_count_fail.out b/tests/expectations/compiler/dynamic_dispatch/dynamic_get_wrong_arg_count_fail.out index f060a2de253..af13ec24864 100644 --- a/tests/expectations/compiler/dynamic_dispatch/dynamic_get_wrong_arg_count_fail.out +++ b/tests/expectations/compiler/dynamic_dispatch/dynamic_get_wrong_arg_count_fail.out @@ -5,10 +5,10 @@ │ │ Help: Pass exactly 4 argument(s) to `_dynamic_get`. ────╯ -[ETYC0372066] Error: `self.caller` is not valid in a finalization context +[ETYC0372066] Error: `std::ctx::caller()` is not valid in a finalization context ╭─[ compiler-test:15:26 ] │ - 15 │ Mapping::set(result, self.caller, val); + 15 │ Mapping::set(result, std::ctx::caller(), val); │ - │ Help: Move `self.caller` out of the `final` block. On-chain code cannot perform this operation. + │ Help: Move `std::ctx::caller()` out of the `final` block. On-chain code cannot perform this operation. ────╯ diff --git a/tests/expectations/compiler/finalize/block_height_fail.out b/tests/expectations/compiler/finalize/block_height_fail.out index 14108416b38..e9ec9eed31d 100644 --- a/tests/expectations/compiler/finalize/block_height_fail.out +++ b/tests/expectations/compiler/finalize/block_height_fail.out @@ -1,7 +1,7 @@ -[ETYC0372034] Error: `block.height` must be inside a `final fn` or a `final` block +[ETYC0372042] Error: only regular `fn`s can be called from a transition body outside a `final {}` block ╭─[ compiler-test:3:27 ] │ - 3 │ assert_eq(height, block.height); + 3 │ assert_eq(height, std::ctx::block_height()); │ - │ Help: Move the `block.height` call into a `final fn` or wrap it in a `final { … }` block. + │ Help: Move the callee out of the `program` block, or call a regular `fn` from this site instead. ───╯ diff --git a/tests/expectations/compiler/finalize/block_timestamp_fail.out b/tests/expectations/compiler/finalize/block_timestamp_fail.out index e91683ce006..5a71cbc56b0 100644 --- a/tests/expectations/compiler/finalize/block_timestamp_fail.out +++ b/tests/expectations/compiler/finalize/block_timestamp_fail.out @@ -1,7 +1,7 @@ -[ETYC0372034] Error: `block.timestamp` must be inside a `final fn` or a `final` block +[ETYC0372042] Error: only regular `fn`s can be called from a transition body outside a `final {}` block ╭─[ compiler-test:3:30 ] │ - 3 │ assert_eq(timestamp, block.timestamp); + 3 │ assert_eq(timestamp, std::ctx::block_timestamp()); │ - │ Help: Move the `block.timestamp` call into a `final fn` or wrap it in a `final { … }` block. + │ Help: Move the callee out of the `program` block, or call a regular `fn` from this site instead. ───╯ diff --git a/tests/expectations/compiler/finalize/get_incorrect_num_operands.out b/tests/expectations/compiler/finalize/get_incorrect_num_operands.out index 3c28f2a06d3..3625327c7e6 100644 --- a/tests/expectations/compiler/finalize/get_incorrect_num_operands.out +++ b/tests/expectations/compiler/finalize/get_incorrect_num_operands.out @@ -5,12 +5,12 @@ │ │ Help: Mapping keys and values must be primitive or simple composite types. Replace this type with a supported one. ───╯ -[ETYC0372147] Error: `self.caller` cannot be used directly inside a `final` block +[ETYC0372147] Error: `std::ctx::caller()` cannot be used directly inside a `final` block ╭─[ compiler-test:11:47 ] │ - 11 │ return final { finalize_decrease_self(self.caller, amount); }; + 11 │ return final { finalize_decrease_self(std::ctx::caller(), amount); }; │ - │ Help: Bind `self.caller` to a variable before the `final` block: `let val = self.caller;`. + │ Help: Bind `std::ctx::caller()` to a variable before the `final` block: `let val = std::ctx::caller();`. ────╯ [ETYC0372006] Error: this call expected 2 argument(s), but 3 were supplied ╭─[ compiler-test:19:5 ] diff --git a/tests/expectations/compiler/finalize/get_or_incorrect_num_operands.out b/tests/expectations/compiler/finalize/get_or_incorrect_num_operands.out index 0d4cbb2b2bc..09708edd839 100644 --- a/tests/expectations/compiler/finalize/get_or_incorrect_num_operands.out +++ b/tests/expectations/compiler/finalize/get_or_incorrect_num_operands.out @@ -5,12 +5,12 @@ │ │ Help: Mapping keys and values must be primitive or simple composite types. Replace this type with a supported one. ───╯ -[ETYC0372147] Error: `self.caller` cannot be used directly inside a `final` block +[ETYC0372147] Error: `std::ctx::caller()` cannot be used directly inside a `final` block ╭─[ compiler-test:11:47 ] │ - 11 │ return final { finalize_decrease_self(self.caller, amount); }; + 11 │ return final { finalize_decrease_self(std::ctx::caller(), amount); }; │ - │ Help: Bind `self.caller` to a variable before the `final` block: `let val = self.caller;`. + │ Help: Bind `std::ctx::caller()` to a variable before the `final` block: `let val = std::ctx::caller();`. ────╯ [ETYC0372006] Error: this call expected 3 argument(s), but 4 were supplied ╭─[ compiler-test:19:5 ] diff --git a/tests/expectations/compiler/finalize/mapping_operations_in_inline_fail.out b/tests/expectations/compiler/finalize/mapping_operations_in_inline_fail.out index 2c4951c371e..778535bd534 100644 --- a/tests/expectations/compiler/finalize/mapping_operations_in_inline_fail.out +++ b/tests/expectations/compiler/finalize/mapping_operations_in_inline_fail.out @@ -15,14 +15,14 @@ [ETYC0372067] Error: this operation can only be used in a `final fn`, a `final` block, or a script ╭─[ compiler-test:11:5 ] │ - 11 │ Mapping::get_or_use(account, self.caller, 1u64); + 11 │ Mapping::get_or_use(account, std::ctx::caller(), 1u64); │ │ Help: Move the operation into a `final fn`, a `final { … }` block inside an entry point, or a script function. ────╯ [ETYC0372034] Error: `Mapping::get_or_use` must be inside a `final fn` or a `final` block ╭─[ compiler-test:11:5 ] │ - 11 │ Mapping::get_or_use(account, self.caller, 1u64); + 11 │ Mapping::get_or_use(account, std::ctx::caller(), 1u64); │ │ Help: Move the `Mapping::get_or_use` call into a `final fn` or wrap it in a `final { … }` block. ────╯ @@ -57,14 +57,14 @@ [ETYC0372067] Error: this operation can only be used in a `final fn`, a `final` block, or a script ╭─[ compiler-test:17:5 ] │ - 17 │ Mapping::get_or_use(account, self.caller, 1u64); + 17 │ Mapping::get_or_use(account, std::ctx::caller(), 1u64); │ │ Help: Move the operation into a `final fn`, a `final { … }` block inside an entry point, or a script function. ────╯ [ETYC0372034] Error: `Mapping::get_or_use` must be inside a `final fn` or a `final` block ╭─[ compiler-test:17:5 ] │ - 17 │ Mapping::get_or_use(account, self.caller, 1u64); + 17 │ Mapping::get_or_use(account, std::ctx::caller(), 1u64); │ │ Help: Move the `Mapping::get_or_use` call into a `final fn` or wrap it in a `final { … }` block. ────╯ diff --git a/tests/expectations/compiler/finalize/set_incorrect_num_operands.out b/tests/expectations/compiler/finalize/set_incorrect_num_operands.out index 8037e3e3977..4b8271aa968 100644 --- a/tests/expectations/compiler/finalize/set_incorrect_num_operands.out +++ b/tests/expectations/compiler/finalize/set_incorrect_num_operands.out @@ -5,12 +5,12 @@ │ │ Help: Mapping keys and values must be primitive or simple composite types. Replace this type with a supported one. ───╯ -[ETYC0372147] Error: `self.caller` cannot be used directly inside a `final` block +[ETYC0372147] Error: `std::ctx::caller()` cannot be used directly inside a `final` block ╭─[ compiler-test:11:47 ] │ - 11 │ return final { finalize_decrease_self(self.caller, amount); }; + 11 │ return final { finalize_decrease_self(std::ctx::caller(), amount); }; │ - │ Help: Bind `self.caller` to a variable before the `final` block: `let val = self.caller;`. + │ Help: Bind `std::ctx::caller()` to a variable before the `final` block: `let val = std::ctx::caller();`. ────╯ [ETYC0372006] Error: this call expected 3 argument(s), but 4 were supplied ╭─[ compiler-test:19:5 ] diff --git a/tests/expectations/compiler/function/program_core_functions_fail.out b/tests/expectations/compiler/function/program_core_functions_fail.out index a345054c3c1..fab7466aa8a 100644 --- a/tests/expectations/compiler/function/program_core_functions_fail.out +++ b/tests/expectations/compiler/function/program_core_functions_fail.out @@ -1,9 +1,9 @@ -[ETYC0372117] Error: expected type `[u8; 31]`, but type `[u8; 32]` was found +[ETYC0372003] Error: expected type `[u8; 31]`, found type `[u8; 32]` ╭─[ compiler-test:3:23 ] │ - 3 │ let d: [u8; 31] = Program::checksum(credits.aleo); + 3 │ let d: [u8; 31] = std::prog::checksum::[credits.aleo](); │ - │ Help: Change the expression to produce type `[u8; 31]`. + │ Help: Change the expression to produce a `[u8; 31]`, or cast it with `as [u8; 31]` if a conversion exists. ───╯ [ETYC0372119] Error: operands of `assert_neq` have different types: `[u8; 32]` and `[u8; 31]` ╭─[ compiler-test:4:5 ] @@ -12,24 +12,24 @@ │ │ Help: Make both operands the same type, e.g. by casting one of them with `as`. ───╯ -[ETYC0372156] Error: `Program::edition` must be called on a program ID, e.g. `foo.aleo` - ╭─[ compiler-test:6:35 ] +[ETYC0372156] Error: `std::prog::edition` must be called on a program ID, e.g. `foo.aleo` + ╭─[ compiler-test:6:39 ] │ - 6 │ let e: u16 = Program::edition(d); + 6 │ let e: u16 = std::prog::edition::[d](); ───╯ [ETYC0372117] Error: expected type `address`, but type `[u8; 31]` was found - ╭─[ compiler-test:6:35 ] + ╭─[ compiler-test:6:39 ] │ - 6 │ let e: u16 = Program::edition(d); + 6 │ let e: u16 = std::prog::edition::[d](); │ │ Help: Change the expression to produce type `address`. ───╯ -[ETYC0372117] Error: expected type `u8`, but type `u16` was found +[ETYC0372003] Error: expected type `u8`, found type `u16` ╭─[ compiler-test:7:17 ] │ - 7 │ let f: u8 = Program::edition(credits.aleo); + 7 │ let f: u8 = std::prog::edition::[credits.aleo](); │ - │ Help: Change the expression to produce type `u8`. + │ Help: Change the expression to produce a `u8`, or cast it with `as u8` if a conversion exists. ───╯ [ETYC0372119] Error: operands of `assert_neq` have different types: `u16` and `u8` ╭─[ compiler-test:8:5 ] @@ -38,32 +38,27 @@ │ │ Help: Make both operands the same type, e.g. by casting one of them with `as`. ───╯ -[ETYC0372156] Error: `Program::function_checksum` must be called on a program ID, e.g. `foo.aleo` - ╭─[ compiler-test:11:50 ] +[ETYC0372156] Error: `std::prog::function_checksum` must be called on a program ID, e.g. `foo.aleo` + ╭─[ compiler-test:11:54 ] │ - 11 │ let g: [u8; 32] = Program::function_checksum(d, 'bar'); + 11 │ let g: [u8; 32] = std::prog::function_checksum::[d, 'bar'](); ────╯ [ETYC0372117] Error: expected type `address`, but type `[u8; 31]` was found - ╭─[ compiler-test:11:50 ] + ╭─[ compiler-test:11:54 ] │ - 11 │ let g: [u8; 32] = Program::function_checksum(d, 'bar'); + 11 │ let g: [u8; 32] = std::prog::function_checksum::[d, 'bar'](); │ │ Help: Change the expression to produce type `address`. ────╯ -[ETYC0372156] Error: the function name must be an identifier literal, e.g. `'foo'` - ╭─[ compiler-test:13:61 ] - │ - 13 │ let h: [u8; 32] = Program::function_checksum(test.aleo, "bar"); -────╯ [ETYC0372117] Error: expected type `identifier`, but type `string` was found - ╭─[ compiler-test:13:61 ] + ╭─[ compiler-test:13:65 ] │ - 13 │ let h: [u8; 32] = Program::function_checksum(test.aleo, "bar"); + 13 │ let h: [u8; 32] = std::prog::function_checksum::[test.aleo, "bar"](); │ │ Help: Change the expression to produce type `identifier`. ────╯ [ETYC0372156] Error: `missing` must be an entry function or a view function of `test.aleo` - ╭─[ compiler-test:15:61 ] + ╭─[ compiler-test:15:65 ] │ - 15 │ let i: [u8; 32] = Program::function_checksum(test.aleo, 'missing'); + 15 │ let i: [u8; 32] = std::prog::function_checksum::[test.aleo, 'missing'](); ────╯ diff --git a/tests/expectations/compiler/function/program_core_functions_long_name_fail.out b/tests/expectations/compiler/function/program_core_functions_long_name_fail.out index 91cba7e62f3..398841d3fcf 100644 --- a/tests/expectations/compiler/function/program_core_functions_long_name_fail.out +++ b/tests/expectations/compiler/function/program_core_functions_long_name_fail.out @@ -1,15 +1,15 @@ -[ETYC0372156] Error: `Program::checksum` must be called on a program ID, e.g. `foo.aleo` - ╭─[ compiler-test:3:41 ] +[ETYC0372156] Error: `std::prog::checksum` must be called on a program ID, e.g. `foo.aleo` + ╭─[ compiler-test:3:45 ] │ - 3 │ let c: [u8; 32] = Program::checksum(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aleo); + 3 │ let c: [u8; 32] = std::prog::checksum::[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aleo](); ───╯ -[ETYC0372156] Error: `Program::edition` must be called on a program ID, e.g. `foo.aleo` - ╭─[ compiler-test:4:35 ] +[ETYC0372156] Error: `std::prog::edition` must be called on a program ID, e.g. `foo.aleo` + ╭─[ compiler-test:4:39 ] │ - 4 │ let d: u16 = Program::edition(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aleo); + 4 │ let d: u16 = std::prog::edition::[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aleo](); ───╯ -[ETYC0372156] Error: `Program::program_owner` must be called on a program ID, e.g. `foo.aleo` - ╭─[ compiler-test:5:45 ] +[ETYC0372156] Error: `std::prog::program_owner` must be called on a program ID, e.g. `foo.aleo` + ╭─[ compiler-test:5:49 ] │ - 5 │ let e: address = Program::program_owner(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aleo); + 5 │ let e: address = std::prog::program_owner::[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aleo](); ───╯ diff --git a/tests/expectations/compiler/function/self_fail.out b/tests/expectations/compiler/function/self_fail.out index 35f5da04df7..bd775252e35 100644 --- a/tests/expectations/compiler/function/self_fail.out +++ b/tests/expectations/compiler/function/self_fail.out @@ -1,5 +1,7 @@ -[EPAR0370047] Error: Unsupported special access +[EPAR0370057] Error: `self` is no longer a valid expression ╭─[ compiler-test:3:16 ] │ 3 │ return self.foo == addr; + │ + │ Help: `self` is reserved and no longer denotes an execution-context value. Use functions from the `std::ctx` module to access caller, signer, block, or network information. ───╯ diff --git a/tests/expectations/compiler/function/self_finalize_fail.out b/tests/expectations/compiler/function/self_finalize_fail.out index c6eaec2c48e..62845f0800a 100644 --- a/tests/expectations/compiler/function/self_finalize_fail.out +++ b/tests/expectations/compiler/function/self_finalize_fail.out @@ -1,14 +1,14 @@ -[ETYC0372147] Error: `self.caller` cannot be used directly inside a `final` block +[ETYC0372147] Error: `std::ctx::caller()` cannot be used directly inside a `final` block ╭─[ compiler-test:6:34 ] │ - 6 │ finalize_matches(self.caller); + 6 │ finalize_matches(std::ctx::caller()); │ - │ Help: Bind `self.caller` to a variable before the `final` block: `let val = self.caller;`. + │ Help: Bind `std::ctx::caller()` to a variable before the `final` block: `let val = std::ctx::caller();`. ───╯ -[ETYC0372066] Error: `self.caller` is not valid in a finalization context +[ETYC0372066] Error: `std::ctx::caller()` is not valid in a finalization context ╭─[ compiler-test:16:21 ] │ - 16 │ assert_eq(addr, self.caller); + 16 │ assert_eq(addr, std::ctx::caller()); │ - │ Help: Move `self.caller` out of the `final` block. On-chain code cannot perform this operation. + │ Help: Move `std::ctx::caller()` out of the `final` block. On-chain code cannot perform this operation. ────╯ diff --git a/tests/expectations/compiler/option/optional_record_fail.out b/tests/expectations/compiler/option/optional_record_fail.out index 7f99c30cbce..b623652f5ce 100644 --- a/tests/expectations/compiler/option/optional_record_fail.out +++ b/tests/expectations/compiler/option/optional_record_fail.out @@ -1,7 +1,7 @@ [ETYC0372160] Error: the type `optional_record_test.aleo::Foo` cannot be wrapped in an optional ╭─[ compiler-test:9:9 ] │ - 9 │ let f: Foo? = Foo { owner: self.signer, val: 5 }; + 9 │ let f: Foo? = Foo { owner: std::ctx::signer(), val: 5 }; │ │ Help: Optionals cannot wrap signatures, finals, mappings, tuples, vectors, records, arrays whose elements are optional-unsafe, or structures containing any such types. ───╯ diff --git a/tests/expectations/compiler/records/return_record_instead_of_unit_fail.out b/tests/expectations/compiler/records/return_record_instead_of_unit_fail.out index add8e936171..4dd104992eb 100644 --- a/tests/expectations/compiler/records/return_record_instead_of_unit_fail.out +++ b/tests/expectations/compiler/records/return_record_instead_of_unit_fail.out @@ -1,7 +1,7 @@ [ETYC0372117] Error: expected type `()`, but type `test.aleo::test_credits` was found ╭─[ compiler-test:8:16 ] │ - 8 │ return test_credits { owner: self.signer, amount }; + 8 │ return test_credits { owner: std::ctx::signer(), amount }; │ │ Help: Change the expression to produce type `()`. ───╯ diff --git a/tests/expectations/compiler/records/self_caller_as_record_owner.out b/tests/expectations/compiler/records/self_caller_as_record_owner.out index 438e3080392..4e8100d239c 100644 --- a/tests/expectations/compiler/records/self_caller_as_record_owner.out +++ b/tests/expectations/compiler/records/self_caller_as_record_owner.out @@ -1,16 +1,16 @@ -[WTYC0372004] Warning: `self.caller` used as the owner of record `test0.aleo::Token` +[WTYC0372004] Warning: `std::ctx::caller()` used as the owner of record `test0.aleo::Token` ╭─[ compiler-test:7:31 ] │ - 7 │ return Token { owner: self.caller }; + 7 │ return Token { owner: std::ctx::caller() }; │ - │ Help: `self.caller` may refer to a program address, which cannot spend records. Use `self.signer` if you want the user that initiated the transaction. + │ Help: `std::ctx::caller()` may return a program address, which cannot spend records. Use `std::ctx::signer()` if you want the user that initiated the transaction. ───╯ -[WTYC0372004] Warning: `self.caller` used as the owner of record `test0.aleo::Token` +[WTYC0372004] Warning: `std::ctx::caller()` used as the owner of record `test0.aleo::Token` ╭─[ compiler-test:11:39 ] │ - 11 │ let t: Token = Token { owner: self.caller }; + 11 │ let t: Token = Token { owner: std::ctx::caller() }; │ - │ Help: `self.caller` may refer to a program address, which cannot spend records. Use `self.signer` if you want the user that initiated the transaction. + │ Help: `std::ctx::caller()` may return a program address, which cannot spend records. Use `std::ctx::signer()` if you want the user that initiated the transaction. ────╯ program test0.aleo; diff --git a/tests/expectations/compiler/view/view_reads_block_timestamp_fail.out b/tests/expectations/compiler/view/view_reads_block_timestamp_fail.out index 1a4ca2b9a65..e33e620f5e9 100644 --- a/tests/expectations/compiler/view/view_reads_block_timestamp_fail.out +++ b/tests/expectations/compiler/view/view_reads_block_timestamp_fail.out @@ -1,7 +1,7 @@ -[ETYC0372034] Error: `block.timestamp` must be inside a `final fn` or a `final` block - ╭─[ compiler-test:8:16 ] +[ETYC0372042] Error: only regular `fn`s can be called from a view function + ╭─[ compiler-test:7:16 ] │ - 8 │ return block.timestamp; + 7 │ return std::ctx::block_timestamp(); │ - │ Help: Move the `block.timestamp` call into a `final fn` or wrap it in a `final { … }` block. + │ Help: Move the callee out of the `program` block, or call a regular `fn` from this site instead. ───╯ diff --git a/tests/expectations/parser-expression/expression/ident.out b/tests/expectations/parser-expression/expression/ident.out index 7a76ff13188..51535bbad60 100644 --- a/tests/expectations/parser-expression/expression/ident.out +++ b/tests/expectations/parser-expression/expression/ident.out @@ -24,8 +24,6 @@ constX test_test -Self - input selfX diff --git a/tests/expectations/parser-expression/expression/path.out b/tests/expectations/parser-expression/expression/path.out index 1032dce03f7..04366752130 100644 --- a/tests/expectations/parser-expression/expression/path.out +++ b/tests/expectations/parser-expression/expression/path.out @@ -6,14 +6,33 @@ xxx::xxx XXX::YYY::ZZZ -Self::pp::qq - foo.aleo::bar foo / bar +[EPAR0370005] Error: expected '&&', '||', '&', '|', '^', '==', '!=', '<', '<=', '>', '>=', '+', '-', '*', '/', '**', '%', '<<', '>>', '(', '[', '{', '.', '::', '?', 'as', found `::` + ╭─[ test_6:1:5 ] + │ + 1 │ Self::pp::qq + │ + │ Help: Replace the highlighted token with what the parser expects, or insert the missing syntax before it. +───╯ +[EPAR0370058] Error: `Self` is reserved for future use + ╭─[ test_6:1:1 ] + │ + 1 │ Self::pp::qq + │ + │ Help: Rename this identifier. `Self` is reserved by the language for an upcoming feature. +───╯ [EPAR0370047] Error: expected '.' -- found '::' ╭─[ test_7:1:5 ] │ 1 │ self::y ───╯ +[EPAR0370057] Error: `self` is no longer a valid expression + ╭─[ test_7:1:1 ] + │ + 1 │ self::y + │ + │ Help: `self` is reserved and no longer denotes an execution-context value. Use functions from the `std::ctx` module to access caller, signer, block, or network information. +───╯ diff --git a/tests/expectations/parser-statement/statement/iteration.out b/tests/expectations/parser-statement/statement/iteration.out index 36e923247c8..3a812711580 100644 --- a/tests/expectations/parser-statement/statement/iteration.out +++ b/tests/expectations/parser-statement/statement/iteration.out @@ -12,7 +12,7 @@ for x: field in 0field..99u8 { } -for x: bool in 0u8..Self { +for x: bool in 0u8..Foo { return 1u8; } @@ -31,7 +31,7 @@ for x in 0field..99u8 { } -for x in 0u8..Self { +for x in 0u8..Foo { return 1u8; } diff --git a/tests/expectations/parser-statement/unreachable/define.out b/tests/expectations/parser-statement/unreachable/define.out index 1fb64176215..ee95eb2dee4 100644 --- a/tests/expectations/parser-statement/unreachable/define.out +++ b/tests/expectations/parser-statement/unreachable/define.out @@ -288,6 +288,13 @@ │ │ Help: Replace the highlighted token with what the parser expects, or insert the missing syntax before it. ───╯ +[EPAR0370057] Error: `self` is no longer a valid expression + ╭─[ test_39:1:1 ] + │ + 1 │ self x = 10u8; + │ + │ Help: `self` is reserved and no longer denotes an execution-context value. Use functions from the `std::ctx` module to access caller, signer, block, or network information. +───╯ [EPAR0370005] Error: expected ';', found `x` ╭─[ test_40:1:6 ] │ @@ -295,6 +302,13 @@ │ │ Help: Replace the highlighted token with what the parser expects, or insert the missing syntax before it. ───╯ +[EPAR0370058] Error: `Self` is reserved for future use + ╭─[ test_40:1:1 ] + │ + 1 │ Self x = 10u8; + │ + │ Help: Rename this identifier. `Self` is reserved by the language for an upcoming feature. +───╯ [EPAR0370005] Error: expected ';', found `x` ╭─[ test_41:1:6 ] │ diff --git a/tests/expectations/parser-statement/unreachable/expect_ident.out b/tests/expectations/parser-statement/unreachable/expect_ident.out index 30a4e024fe7..618e25e43f9 100644 --- a/tests/expectations/parser-statement/unreachable/expect_ident.out +++ b/tests/expectations/parser-statement/unreachable/expect_ident.out @@ -251,12 +251,10 @@ │ 1 │ x::self ───╯ -[EPAR0370003] Error: unexpected end of file - ╭─[ test_47:1:8 ] +[EPAR0370047] Error: expected identifier after :: + ╭─[ test_47:1:4 ] │ 1 │ x::Self - │ - │ Help: The parser reached the end of the file while still expecting more input. Complete the current item. Common causes are a missing `}`, `)`, or `;`. ───╯ [EPAR0370047] Error: expected identifier after :: ╭─[ test_48:1:4 ] diff --git a/tests/expectations/parser/program/network_id.out b/tests/expectations/parser/program/network_id.out index 518ee292ffc..fb22976e603 100644 --- a/tests/expectations/parser/program/network_id.out +++ b/tests/expectations/parser/program/network_id.out @@ -1,7 +1,7 @@ program test.aleo { } fn main(a: address) { - assert_eq(_network_id(), 1u32); + assert_eq(std::ctx::network_id(), 1u32); return a; } diff --git a/tests/expectations/parser/program/removed_self_block_network_sugar_fail.out b/tests/expectations/parser/program/removed_self_block_network_sugar_fail.out new file mode 100644 index 00000000000..711f0269c6b --- /dev/null +++ b/tests/expectations/parser/program/removed_self_block_network_sugar_fail.out @@ -0,0 +1,91 @@ +[EPAR0370056] Error: the `self.caller` syntax has been removed + ╭─[ test:3:16 ] + │ + 3 │ return self.caller; + │ + │ Help: Use `std::ctx::caller()` instead. Execution-context accessors now live in the `std::ctx` module. +───╯ +[EPAR0370056] Error: the `self.signer` syntax has been removed + ╭─[ test:6:16 ] + │ + 6 │ return self.signer; + │ + │ Help: Use `std::ctx::signer()` instead. Execution-context accessors now live in the `std::ctx` module. +───╯ +[EPAR0370056] Error: the `self.address` syntax has been removed + ╭─[ test:9:16 ] + │ + 9 │ return self.address; + │ + │ Help: Use `std::ctx::addr()` instead. Execution-context accessors now live in the `std::ctx` module. +───╯ +[EPAR0370056] Error: the `self.id` syntax has been removed + ╭─[ test:12:16 ] + │ + 12 │ return self.id; + │ + │ Help: Use `std::ctx::id()` instead. Execution-context accessors now live in the `std::ctx` module. +────╯ +[EPAR0370056] Error: the `self.checksum` syntax has been removed + ╭─[ test:15:16 ] + │ + 15 │ return self.checksum; + │ + │ Help: Use `std::ctx::checksum()` instead. Execution-context accessors now live in the `std::ctx` module. +────╯ +[EPAR0370056] Error: the `self.edition` syntax has been removed + ╭─[ test:18:16 ] + │ + 18 │ return self.edition; + │ + │ Help: Use `std::ctx::edition()` instead. Execution-context accessors now live in the `std::ctx` module. +────╯ +[EPAR0370056] Error: the `self.program_owner` syntax has been removed + ╭─[ test:21:16 ] + │ + 21 │ return self.program_owner; + │ + │ Help: Use `std::ctx::program_owner()` instead. Execution-context accessors now live in the `std::ctx` module. +────╯ +[EPAR0370056] Error: the `block.height` syntax has been removed + ╭─[ test:24:16 ] + │ + 24 │ return block.height; + │ + │ Help: Use `std::ctx::block_height()` instead. Execution-context accessors now live in the `std::ctx` module. +────╯ +[EPAR0370056] Error: the `block.timestamp` syntax has been removed + ╭─[ test:27:16 ] + │ + 27 │ return block.timestamp; + │ + │ Help: Use `std::ctx::block_timestamp()` instead. Execution-context accessors now live in the `std::ctx` module. +────╯ +[EPAR0370056] Error: the `network.id` syntax has been removed + ╭─[ test:30:16 ] + │ + 30 │ return network.id; + │ + │ Help: Use `std::ctx::network_id()` instead. Execution-context accessors now live in the `std::ctx` module. +────╯ +[EPAR0370057] Error: `self` is no longer a valid expression + ╭─[ test:33:17 ] + │ + 33 │ let s = self; + │ + │ Help: `self` is reserved and no longer denotes an execution-context value. Use functions from the `std::ctx` module to access caller, signer, block, or network information. +────╯ +[EPAR0370057] Error: `block` is no longer a valid expression + ╭─[ test:37:17 ] + │ + 37 │ let b = block; + │ + │ Help: `block` is reserved and no longer denotes an execution-context value. Use functions from the `std::ctx` module to access caller, signer, block, or network information. +────╯ +[EPAR0370057] Error: `network` is no longer a valid expression + ╭─[ test:41:17 ] + │ + 41 │ let n = network; + │ + │ Help: `network` is reserved and no longer denotes an execution-context value. Use functions from the `std::ctx` module to access caller, signer, block, or network information. +────╯ diff --git a/tests/expectations/parser/program/reserved_self_upper_fail.out b/tests/expectations/parser/program/reserved_self_upper_fail.out new file mode 100644 index 00000000000..bae7c4eb860 --- /dev/null +++ b/tests/expectations/parser/program/reserved_self_upper_fail.out @@ -0,0 +1,31 @@ +[EPAR0370005] Error: expected ';', found `::` + ╭─[ test:3:20 ] + │ + 3 │ return Self::ctx::caller(); + │ + │ Help: Replace the highlighted token with what the parser expects, or insert the missing syntax before it. +───╯ +[EPAR0370047] Error: expected parameter name + ╭─[ test:5:20 ] + │ + 5 │ fn binding_use(Self: u32) -> u32 { +───╯ +[EPAR0370047] Error: expected struct name + ╭─[ test:8:12 ] + │ + 8 │ struct Self { +───╯ +[EPAR0370058] Error: `Self` is reserved for future use + ╭─[ test:3:16 ] + │ + 3 │ return Self::ctx::caller(); + │ + │ Help: Rename this identifier. `Self` is reserved by the language for an upcoming feature. +───╯ +[EPAR0370058] Error: `Self` is reserved for future use + ╭─[ test:6:16 ] + │ + 6 │ return Self; + │ + │ Help: Rename this identifier. `Self` is reserved by the language for an upcoming feature. +───╯ diff --git a/tests/expectations/parser/program/special_address.out b/tests/expectations/parser/program/special_address.out index 82f92186ff9..2b6711195c8 100644 --- a/tests/expectations/parser/program/special_address.out +++ b/tests/expectations/parser/program/special_address.out @@ -1,8 +1,8 @@ program test.aleo { mapping Yo: address => u32; fn main(a: address) { - assert_eq(a, _self_caller()); - assert_eq(a, _self_address()); + assert_eq(a, std::ctx::caller()); + assert_eq(a, std::ctx::addr()); assert_eq(a, hello.aleo); return foo.aleo; } diff --git a/tests/expectations/parser/unreachable/eat_ident.out b/tests/expectations/parser/unreachable/eat_ident.out index da610d6207a..80d6310d74c 100644 --- a/tests/expectations/parser/unreachable/eat_ident.out +++ b/tests/expectations/parser/unreachable/eat_ident.out @@ -48,14 +48,3 @@ │ 10 │ struct ] ────╯ -[EPAR0370027] Error: missing a program scope in a Leo file - ╭─[ test:1:1 ] - │ - 1 │ ╭─▶ struct import - ┆ ┆ - 56 │ ├─▶ program test.aleo {} - │ │ - │ ╰────────────────────────── here - │ - │ Help: Add a program scope of the form `program .aleo { ... }` to the Leo file. -────╯ diff --git a/tests/tests/cli/test_devnode_persistent_storage/contents/src/main.leo b/tests/tests/cli/test_devnode_persistent_storage/contents/src/main.leo index b2cf741c370..5ac943d0357 100644 --- a/tests/tests/cli/test_devnode_persistent_storage/contents/src/main.leo +++ b/tests/tests/cli/test_devnode_persistent_storage/contents/src/main.leo @@ -3,7 +3,7 @@ program persistent_counter.aleo { mapping counts: address => u64; fn increment() -> Final { - let caller: address = self.caller; + let caller: address = std::ctx::caller(); return final { let current: u64 = counts.get_or_use(caller, 0u64); counts.set(caller, current + 1u64); diff --git a/tests/tests/compiler/address/self_address_fail.leo b/tests/tests/compiler/address/self_address_fail.leo index 75fde69361b..dcb4add7e16 100644 --- a/tests/tests/compiler/address/self_address_fail.leo +++ b/tests/tests/compiler/address/self_address_fail.leo @@ -1,10 +1,10 @@ program test.aleo { fn main() -> bool { - return self.address; + return std::ctx::addr(); } fn next() -> bool { - let a = self.address; + let a = std::ctx::addr(); return a; } diff --git a/tests/tests/compiler/address/special_address.leo b/tests/tests/compiler/address/special_address.leo index 65864b56b89..c62589bbe01 100644 --- a/tests/tests/compiler/address/special_address.leo +++ b/tests/tests/compiler/address/special_address.leo @@ -2,9 +2,9 @@ program test.aleo { mapping Yo: address => u32; fn main(a: address) -> address { - assert_eq(a, self.caller); - assert_eq(a, self.address); - assert_eq(a, self.id); + assert_eq(a, std::ctx::caller()); + assert_eq(a, std::ctx::addr()); + assert_eq(a, std::ctx::id()); assert_eq(a, hello.aleo); return foo.aleo; } diff --git a/tests/tests/compiler/array/array_in_composite_data_types.leo b/tests/tests/compiler/array/array_in_composite_data_types.leo index f98ccd29e1a..b7b98f8f1bc 100644 --- a/tests/tests/compiler/array/array_in_composite_data_types.leo +++ b/tests/tests/compiler/array/array_in_composite_data_types.leo @@ -12,7 +12,7 @@ program test.aleo { return ( a[0u32][0u32], bar { data: [1u8, 1u8, 1u8, 1u8, 1u8, 1u8, 1u8, 1u8] }, - floo { owner: self.signer, data: [1u8, 1u8, 1u8, 1u8, 1u8, 1u8, 1u8, 1u8] }, + floo { owner: std::ctx::signer(), data: [1u8, 1u8, 1u8, 1u8, 1u8, 1u8, 1u8, 1u8] }, ); } diff --git a/tests/tests/compiler/array/array_in_mapping.leo b/tests/tests/compiler/array/array_in_mapping.leo index 0827da6225b..9ef9f77b661 100644 --- a/tests/tests/compiler/array/array_in_mapping.leo +++ b/tests/tests/compiler/array/array_in_mapping.leo @@ -2,7 +2,7 @@ program test.aleo { mapping data: address => [bool; 8]; fn foo(a: [bool; 8]) -> Final { - let caller = self.caller; + let caller = std::ctx::caller(); return final { fin_foo(caller, a); }; } diff --git a/tests/tests/compiler/array/array_write.leo b/tests/tests/compiler/array/array_write.leo index 6de7190b03f..131999fce2b 100644 --- a/tests/tests/compiler/array/array_write.leo +++ b/tests/tests/compiler/array/array_write.leo @@ -58,7 +58,7 @@ program test.aleo { fn f_record() -> (R, Final) { let fut: Final = final { f_finalize(1u8); }; - let r: R = R { owner: self.signer, x: 1u8 }; + let r: R = R { owner: std::ctx::signer(), x: 1u8 }; r.x = 2u8; return (r, fut); } diff --git a/tests/tests/compiler/async_blocks/allowed_expr_in_async_block.leo b/tests/tests/compiler/async_blocks/allowed_expr_in_async_block.leo index e9d544f1d3c..56e1eac05c9 100644 --- a/tests/tests/compiler/async_blocks/allowed_expr_in_async_block.leo +++ b/tests/tests/compiler/async_blocks/allowed_expr_in_async_block.leo @@ -3,9 +3,9 @@ program test.aleo { fn t1() -> Final { return final { - let b = block.height; - let t = block.timestamp; - let i = network.id; + let b = std::ctx::block_height(); + let t = std::ctx::block_timestamp(); + let i = std::ctx::network_id(); foo.set(0u32, 0u32); let s1 = foo.get(0u32); let s2 = foo.get_or_use(0u32, 0u32); diff --git a/tests/tests/compiler/async_blocks/async_block_with_method_calls.leo b/tests/tests/compiler/async_blocks/async_block_with_method_calls.leo index bb0d28046d2..5a18feef69e 100644 --- a/tests/tests/compiler/async_blocks/async_block_with_method_calls.leo +++ b/tests/tests/compiler/async_blocks/async_block_with_method_calls.leo @@ -10,7 +10,7 @@ program test.aleo { } fn finalize_self_caller() -> Final { - let caller = self.caller; + let caller = std::ctx::caller(); return final { let current_value: u8 = values.get_or_use(0u8, 0u8); values.set(0u8, current_value + 1u8); diff --git a/tests/tests/compiler/async_blocks/future_access_tuple_fail.leo b/tests/tests/compiler/async_blocks/future_access_tuple_fail.leo index 88b4058e37c..32520cd860b 100644 --- a/tests/tests/compiler/async_blocks/future_access_tuple_fail.leo +++ b/tests/tests/compiler/async_blocks/future_access_tuple_fail.leo @@ -24,7 +24,7 @@ program test_credits.aleo { fn send_credits(input: credits.aleo::credits, amount: u64) -> (credits.aleo::credits, Final) { let start: (credits.aleo::credits, Final) = credits.aleo::transfer_private_to_public( input, - self.address, + std::ctx::addr(), amount, ); let after: (u8, credits.aleo::credits) = (1u8, start.0); diff --git a/tests/tests/compiler/async_blocks/future_in_tuple.leo b/tests/tests/compiler/async_blocks/future_in_tuple.leo index 054b6711219..a4a16824423 100644 --- a/tests/tests/compiler/async_blocks/future_in_tuple.leo +++ b/tests/tests/compiler/async_blocks/future_in_tuple.leo @@ -20,7 +20,7 @@ program test_credits.aleo { fn send_credits(input: credits.aleo::credits, amount: u64) -> (credits.aleo::credits, Final) { let result: (credits.aleo::credits, Final) = credits.aleo::transfer_private_to_public( input, - self.address, + std::ctx::addr(), amount, ); return ( diff --git a/tests/tests/compiler/async_blocks/future_in_tuple_check_fail.leo b/tests/tests/compiler/async_blocks/future_in_tuple_check_fail.leo index 5857413ddb1..44fa3cdd5b7 100644 --- a/tests/tests/compiler/async_blocks/future_in_tuple_check_fail.leo +++ b/tests/tests/compiler/async_blocks/future_in_tuple_check_fail.leo @@ -20,12 +20,12 @@ program test_credits.aleo { fn send_credits(input: credits.aleo::credits, amount: u64) -> (credits.aleo::credits, Final) { let result: (credits.aleo::credits, Final) = credits.aleo::transfer_private_to_public( input, - self.address, + std::ctx::addr(), amount, ); let result2: (credits.aleo::credits, Final) = credits.aleo::transfer_private_to_public( input, - self.address, + std::ctx::addr(), amount, ); return ( diff --git a/tests/tests/compiler/async_blocks/future_not_all_passed_to_async_block_fail.leo b/tests/tests/compiler/async_blocks/future_not_all_passed_to_async_block_fail.leo index f043e00c856..0fb01438762 100644 --- a/tests/tests/compiler/async_blocks/future_not_all_passed_to_async_block_fail.leo +++ b/tests/tests/compiler/async_blocks/future_not_all_passed_to_async_block_fail.leo @@ -2,12 +2,12 @@ program child.aleo { mapping count: address => field; fn foo() -> Final { - let caller = self.caller; + let caller = std::ctx::caller(); return final { finalize_foo(caller); }; } fn boo() -> Final { - let caller = self.caller; + let caller = std::ctx::caller(); return final { finalize_boo(caller); }; } diff --git a/tests/tests/compiler/async_blocks/future_type_inference.leo b/tests/tests/compiler/async_blocks/future_type_inference.leo index d42f88620c5..af185d50ea0 100644 --- a/tests/tests/compiler/async_blocks/future_type_inference.leo +++ b/tests/tests/compiler/async_blocks/future_type_inference.leo @@ -27,7 +27,7 @@ program multi_token_support_program.aleo { fn mint_private() -> (Token, Final) { let f: Final = final { assert_eq(1u8, 1u8); }; - return (Token { owner: self.signer, amount: 100u64 }, f); + return (Token { owner: std::ctx::signer(), amount: 100u64 }, f); } @noupgrade @@ -45,7 +45,7 @@ program mtsp_credits.aleo { ) -> (credits.aleo::credits, multi_token_support_program.aleo::Token, Final) { let transfer_output: (credits.aleo::credits, Final) = credits.aleo::transfer_private_to_public( input_record, - self.address, + std::ctx::addr(), amount, ); let mint_output: (multi_token_support_program.aleo::Token, Final) = multi_token_support_program.aleo::mint_private(); diff --git a/tests/tests/compiler/async_blocks/invalid_expr_in_async_block_fail.leo b/tests/tests/compiler/async_blocks/invalid_expr_in_async_block_fail.leo index 62096db06d2..da1a2ab5609 100644 --- a/tests/tests/compiler/async_blocks/invalid_expr_in_async_block_fail.leo +++ b/tests/tests/compiler/async_blocks/invalid_expr_in_async_block_fail.leo @@ -1,8 +1,8 @@ program test.aleo { fn t1() { let f1 = final { - let s = self.signer; - let c = self.caller; + let s = std::ctx::signer(); + let c = std::ctx::caller(); }; } diff --git a/tests/tests/compiler/async_blocks/nested.leo b/tests/tests/compiler/async_blocks/nested.leo index 125c1941cba..42d88523744 100644 --- a/tests/tests/compiler/async_blocks/nested.leo +++ b/tests/tests/compiler/async_blocks/nested.leo @@ -14,7 +14,7 @@ program test_dep.aleo { Mapping::set(Yo, a, b); let c: u32 = a + b; }; - let l: yeets = yeets { owner: self.signer, val: 1u32 }; + let l: yeets = yeets { owner: std::ctx::signer(), val: 1u32 }; return (l, f); } diff --git a/tests/tests/compiler/async_blocks/partial_type_specification.leo b/tests/tests/compiler/async_blocks/partial_type_specification.leo index 9b3e2a12c84..e2577fd3369 100644 --- a/tests/tests/compiler/async_blocks/partial_type_specification.leo +++ b/tests/tests/compiler/async_blocks/partial_type_specification.leo @@ -13,13 +13,13 @@ program test_dep.aleo { Mapping::set(Yo, a, b); let c: u32 = a + b; }; - let l: yeets = yeets { owner: self.signer, val: 1u32 }; + let l: yeets = yeets { owner: std::ctx::signer(), val: 1u32 }; return (l, f); } fn main_dep_2(a: u32) -> (yeets, Final) { let f: Final = final { Mapping::set(Yo, 1u32, 1u32); }; - let l: yeets = yeets { owner: self.signer, val: 1u32 }; + let l: yeets = yeets { owner: std::ctx::signer(), val: 1u32 }; return (l, f); } diff --git a/tests/tests/compiler/async_blocks/self_in_async_block_fail.leo b/tests/tests/compiler/async_blocks/self_in_async_block_fail.leo index c82e13d92bf..b2ecb3fc591 100644 --- a/tests/tests/compiler/async_blocks/self_in_async_block_fail.leo +++ b/tests/tests/compiler/async_blocks/self_in_async_block_fail.leo @@ -1,8 +1,8 @@ program test.aleo { fn t1() { let f1 = final { - let c = self.caller; - let s = self.signer; + let c = std::ctx::caller(); + let s = std::ctx::signer(); }; } diff --git a/tests/tests/compiler/bugs/b28610.leo b/tests/tests/compiler/bugs/b28610.leo index da29e71c6c1..0defc501007 100644 --- a/tests/tests/compiler/bugs/b28610.leo +++ b/tests/tests/compiler/bugs/b28610.leo @@ -4,7 +4,7 @@ program b28610.aleo { } fn foo() -> Final { - let signer = self.signer; + let signer = std::ctx::signer(); return final { bar(signer); }; } diff --git a/tests/tests/compiler/bugs/b28611.leo b/tests/tests/compiler/bugs/b28611.leo index b37631dc837..ac50efe4ac1 100644 --- a/tests/tests/compiler/bugs/b28611.leo +++ b/tests/tests/compiler/bugs/b28611.leo @@ -4,8 +4,8 @@ program test.aleo { fn foo(sig: signature, x: u32, y: u32) { // ensure that the caller provided the correct signature let t: (u32, u32) = (x, y); - let b: bool = sig.verify(self.caller, t); - let c: bool = sig.verify(self.caller, m); + let b: bool = sig.verify(std::ctx::caller(), t); + let c: bool = sig.verify(std::ctx::caller(), m); } @noupgrade diff --git a/tests/tests/compiler/bugs/b28614.leo b/tests/tests/compiler/bugs/b28614.leo index 48d69fc18f3..2d6f3d0941a 100644 --- a/tests/tests/compiler/bugs/b28614.leo +++ b/tests/tests/compiler/bugs/b28614.leo @@ -1,13 +1,13 @@ program test.aleo { fn bar() { - let x: u32 = self.caller; - let y: u8 = self.caller; + let x: u32 = std::ctx::caller(); + let y: u8 = std::ctx::caller(); let z: u8 = 0u8; - z = self.caller; + z = std::ctx::caller(); let w: field = 0field; - w = self.signer; + w = std::ctx::signer(); } @noupgrade diff --git a/tests/tests/compiler/bugs/unknown_variable_fail.leo b/tests/tests/compiler/bugs/unknown_variable_fail.leo index 2a86792e68b..01dda4335bc 100644 --- a/tests/tests/compiler/bugs/unknown_variable_fail.leo +++ b/tests/tests/compiler/bugs/unknown_variable_fail.leo @@ -31,7 +31,7 @@ program test.aleo { fn init(b: bool) -> (address, Final) { return ( - self.caller, + std::ctx::caller(), final { finalize_init(caller); }, diff --git a/tests/tests/compiler/const_generics/const_generics_invalid_context_fail.leo b/tests/tests/compiler/const_generics/const_generics_invalid_context_fail.leo index 5ece2ca4c20..bc538297fd8 100644 --- a/tests/tests/compiler/const_generics/const_generics_invalid_context_fail.leo +++ b/tests/tests/compiler/const_generics/const_generics_invalid_context_fail.leo @@ -7,19 +7,17 @@ fn foo1::[N: u32](x: u32) -> u32 { return N; } -final fn foo2::[N: u32](x: u32) {} - fn baz::[N: u32]() {} program const_generics.aleo { fn main() -> Final { - return final { foo2::[1u32](0u32); }; + return final { baz::[1u32](); }; } fn bar1::[N: u32]() {} fn bar2::[N: u32]() -> Final { - return final { foo2::[1u32](0u32); }; + return final { baz::[N](); }; } @noupgrade diff --git a/tests/tests/compiler/const_generics/final_fn_const_generics.leo b/tests/tests/compiler/const_generics/final_fn_const_generics.leo new file mode 100644 index 00000000000..8fbec4800d0 --- /dev/null +++ b/tests/tests/compiler/const_generics/final_fn_const_generics.leo @@ -0,0 +1,46 @@ +// Positive coverage for `final fn` declarations with generic const parameters. +// `final fn`s are always inlined into their `final {}` call site +// (`function_inlining/transform.rs:278`), so monomorphization can specialize +// the body for each concrete const argument at the call site. The patterns +// below exercise the cases the language is expected to handle: +// +// 1. A `final fn` with a single u32 const generic, invoked from a `final {}`. +// 2. A `final fn` with an `address` const generic. +// 3. A `final fn` calling another `final fn` with const generics (both inline). +// 4. A `final fn` threading its own const generic into a generic callee. +// 5. Multiple const generic parameters on a single `final fn`. + +final fn scaled::[N: u32](x: u32) -> u32 { + return x + N; +} + +final fn for_program::[PROG: address]() -> address { + return PROG; +} + +final fn double_scaled::[N: u32](x: u32) -> u32 { + return scaled::[N](x) + scaled::[N](x); +} + +final fn forwarded::[A: u32](x: u32) -> u32 { + return scaled::[A](x); +} + +final fn shifted::[N: u32, M: u32](x: u32) -> u32 { + return scaled::[N](x) + M; +} + +program test.aleo { + fn run() -> Final { + return final { + assert_eq(scaled::[5u32](10u32), 15u32); + assert_eq(double_scaled::[3u32](7u32), 20u32); + assert_eq(forwarded::[2u32](8u32), 10u32); + assert_eq(shifted::[4u32, 6u32](1u32), 11u32); + assert_eq(for_program::[test.aleo](), test.aleo); + }; + } + + @noupgrade + constructor() {} +} diff --git a/tests/tests/compiler/const_generics/unresolved_struct_type_fail.leo b/tests/tests/compiler/const_generics/unresolved_struct_type_fail.leo index 68a5eea0bfa..6185207a020 100644 --- a/tests/tests/compiler/const_generics/unresolved_struct_type_fail.leo +++ b/tests/tests/compiler/const_generics/unresolved_struct_type_fail.leo @@ -3,13 +3,13 @@ struct Foo::[N: address] { } struct Goo::[P: u32] { - z: Foo::[self.caller], + z: Foo::[_self_caller()], } program b28668.aleo { fn main(y: u32) -> u32 { let g: Goo::[y] = Goo::[y] { - z: Foo::[self.caller] { x: 5 }, + z: Foo::[_self_caller()] { x: 5 }, }; return g.z.x; } diff --git a/tests/tests/compiler/constants/block_height_type_fail.leo b/tests/tests/compiler/constants/block_height_type_fail.leo index 1afcda67999..4801b9766a6 100644 --- a/tests/tests/compiler/constants/block_height_type_fail.leo +++ b/tests/tests/compiler/constants/block_height_type_fail.leo @@ -1,5 +1,5 @@ final fn bar() { - let x: u64 = block.height; + let x: u64 = std::ctx::block_height(); } program test.aleo { diff --git a/tests/tests/compiler/constants/block_timestamp_type_fail.leo b/tests/tests/compiler/constants/block_timestamp_type_fail.leo index 7acf35ba52a..3418d8d2aba 100644 --- a/tests/tests/compiler/constants/block_timestamp_type_fail.leo +++ b/tests/tests/compiler/constants/block_timestamp_type_fail.leo @@ -1,5 +1,5 @@ final fn bar() { - let x: u32 = block.timestamp; + let x: u32 = std::ctx::block_timestamp(); } program test.aleo { diff --git a/tests/tests/compiler/constants/constant_finalize.leo b/tests/tests/compiler/constants/constant_finalize.leo index b5c9c809f3f..73bba8ca594 100644 --- a/tests/tests/compiler/constants/constant_finalize.leo +++ b/tests/tests/compiler/constants/constant_finalize.leo @@ -5,7 +5,7 @@ program test.aleo { mapping values: u8 => u8; fn finalize_self_caller() -> Final { - let caller = self.caller; + let caller = std::ctx::caller(); return final { finalize_finalize_self_caller(caller); }; } diff --git a/tests/tests/compiler/constructor/checksum_constructor_does_not_match_fail.leo b/tests/tests/compiler/constructor/checksum_constructor_does_not_match_fail.leo index a2099f262c8..b051751fedb 100644 --- a/tests/tests/compiler/constructor/checksum_constructor_does_not_match_fail.leo +++ b/tests/tests/compiler/constructor/checksum_constructor_does_not_match_fail.leo @@ -5,9 +5,9 @@ program test.aleo { @checksum(mapping = "test.aleo::expected_checksum", key = "true") constructor() { - if self.edition >= 0u16 { + if std::ctx::edition() >= 0u16 { let expected: [u8; 32] = Mapping::get(expected_checksum, true); - assert_eq(self.checksum, expected); + assert_eq(std::ctx::checksum(), expected); } } } diff --git a/tests/tests/compiler/constructor/constructor_label_stability.leo b/tests/tests/compiler/constructor/constructor_label_stability.leo index d7a2c8d6c7e..04529804973 100644 --- a/tests/tests/compiler/constructor/constructor_label_stability.leo +++ b/tests/tests/compiler/constructor/constructor_label_stability.leo @@ -7,11 +7,11 @@ program test.aleo { @custom constructor() { - let current_edition: u16 = self.edition; + let current_edition: u16 = std::ctx::edition(); if current_edition > 0u16 { - let current_checksum: [u8; 32] = self.checksum; + let current_checksum: [u8; 32] = std::ctx::checksum(); } else { - admin.set(true, self.program_owner); + admin.set(true, std::ctx::program_owner()); } } } diff --git a/tests/tests/compiler/constructor/declared_constructor.leo b/tests/tests/compiler/constructor/declared_constructor.leo index 4de1968b2a2..3ba8450ca99 100644 --- a/tests/tests/compiler/constructor/declared_constructor.leo +++ b/tests/tests/compiler/constructor/declared_constructor.leo @@ -3,19 +3,19 @@ program test.aleo { mapping admin: bool => address; fn set_expected(checksum: [u8; 32]) -> Final { - let caller = self.caller; + let caller = std::ctx::caller(); return final { set_expected_(caller, checksum); }; } @custom constructor() { - let current_edition: u16 = self.edition; + let current_edition: u16 = std::ctx::edition(); if current_edition > 0u16 { let expected_checksum: [u8; 32] = expected.get(true); - let current_checksum: [u8; 32] = self.checksum; + let current_checksum: [u8; 32] = std::ctx::checksum(); assert_eq(expected_checksum, current_checksum); } else { - admin.set(true, self.program_owner); + admin.set(true, std::ctx::program_owner()); } } } diff --git a/tests/tests/compiler/constructor/empty_custom_constructor_fail.leo b/tests/tests/compiler/constructor/empty_custom_constructor_fail.leo index d774420a1ac..cabf4b73777 100644 --- a/tests/tests/compiler/constructor/empty_custom_constructor_fail.leo +++ b/tests/tests/compiler/constructor/empty_custom_constructor_fail.leo @@ -3,6 +3,6 @@ program constr.aleo { @custom constructor() { - let x = self.program_owner; + let x = std::ctx::program_owner(); } } diff --git a/tests/tests/compiler/constructor/not_upgradable_constructor_does_not_match_fail.leo b/tests/tests/compiler/constructor/not_upgradable_constructor_does_not_match_fail.leo index c5558367612..94cc44169f2 100644 --- a/tests/tests/compiler/constructor/not_upgradable_constructor_does_not_match_fail.leo +++ b/tests/tests/compiler/constructor/not_upgradable_constructor_does_not_match_fail.leo @@ -3,6 +3,6 @@ program test.aleo { @noupgrade constructor() { - assert_eq(self.edition, 0u16); + assert_eq(std::ctx::edition(), 0u16); } } diff --git a/tests/tests/compiler/dyn_record/dyn_record_external_struct.leo b/tests/tests/compiler/dyn_record/dyn_record_external_struct.leo index e0cda1345a5..7c282a68afc 100644 --- a/tests/tests/compiler/dyn_record/dyn_record_external_struct.leo +++ b/tests/tests/compiler/dyn_record/dyn_record_external_struct.leo @@ -9,7 +9,7 @@ program token.aleo { } fn mint(m: Metadata) -> Token { - return Token { owner: self.signer, meta: m }; + return Token { owner: std::ctx::signer(), meta: m }; } @noupgrade diff --git a/tests/tests/compiler/dynamic_dispatch/dynamic_get_wrong_arg_count_fail.leo b/tests/tests/compiler/dynamic_dispatch/dynamic_get_wrong_arg_count_fail.leo index 17e186c1d7f..dce3c596dee 100644 --- a/tests/tests/compiler/dynamic_dispatch/dynamic_get_wrong_arg_count_fail.leo +++ b/tests/tests/compiler/dynamic_dispatch/dynamic_get_wrong_arg_count_fail.leo @@ -12,5 +12,5 @@ program test.aleo { final fn finalize_read(prog: field, net: field, m: field) { let val: u64 = _dynamic_get::[u64](prog, net, m); - Mapping::set(result, self.caller, val); + Mapping::set(result, std::ctx::caller(), val); } diff --git a/tests/tests/compiler/dynamic_dispatch/static_external_future.leo b/tests/tests/compiler/dynamic_dispatch/static_external_future.leo index 1cfb6a1efa3..3b3b63f4083 100644 --- a/tests/tests/compiler/dynamic_dispatch/static_external_future.leo +++ b/tests/tests/compiler/dynamic_dispatch/static_external_future.leo @@ -27,7 +27,7 @@ program test_static.aleo { constructor() {} fn test_withdraw_private(amount: u64) -> (credits.aleo::credits, Final) { - let (cred, f): (credits.aleo::credits, Final) = credits.aleo::transfer_public_to_private(self.signer, amount); + let (cred, f): (credits.aleo::credits, Final) = credits.aleo::transfer_public_to_private(std::ctx::signer(), amount); return (cred, final { f.run(); }); } } diff --git a/tests/tests/compiler/examples/auction.leo b/tests/tests/compiler/examples/auction.leo index 2a835d0048e..cc97506279e 100644 --- a/tests/tests/compiler/examples/auction.leo +++ b/tests/tests/compiler/examples/auction.leo @@ -20,7 +20,7 @@ program test.aleo { // The address of the auction runner is aleo1fxs9s0w97lmkwlcmgn0z3nuxufdee5yck9wqrs0umevp7qs0sg9q5xxxzh. fn place_bid(bidder: address, amount: u64) -> Bid { // Ensure the caller is the auction bidder. - assert_eq(self.caller, bidder); + assert_eq(std::ctx::caller(), bidder); // Return a new 'Bid' record for the auction bidder. return Bid { owner: aleo1fxs9s0w97lmkwlcmgn0z3nuxufdee5yck9wqrs0umevp7qs0sg9q5xxxzh, @@ -38,7 +38,7 @@ program test.aleo { // In the event of a tie, the first bid is selected. fn resolve(first: Bid, second: Bid) -> Bid { // Ensure the caller is the auctioneer. - assert_eq(self.caller, aleo1fxs9s0w97lmkwlcmgn0z3nuxufdee5yck9wqrs0umevp7qs0sg9q5xxxzh); + assert_eq(std::ctx::caller(), aleo1fxs9s0w97lmkwlcmgn0z3nuxufdee5yck9wqrs0umevp7qs0sg9q5xxxzh); // Resolve the winner of the auction. if (first.amount >= second.amount) { return first; @@ -53,7 +53,7 @@ program test.aleo { // Assumes that the function is invoked only after all bids have been resolved. fn finish(bid: Bid) -> Bid { // Ensure the caller is the auctioneer. - assert_eq(self.caller, aleo1fxs9s0w97lmkwlcmgn0z3nuxufdee5yck9wqrs0umevp7qs0sg9q5xxxzh); + assert_eq(std::ctx::caller(), aleo1fxs9s0w97lmkwlcmgn0z3nuxufdee5yck9wqrs0umevp7qs0sg9q5xxxzh); // Return 'is_winner' as 'true' in the winning 'Bid'. return Bid { owner: bid.bidder, bidder: bid.bidder, amount: bid.amount, is_winner: true }; } diff --git a/tests/tests/compiler/examples/basic_bank.leo b/tests/tests/compiler/examples/basic_bank.leo index 722eb0fee8e..5cec3c8399b 100644 --- a/tests/tests/compiler/examples/basic_bank.leo +++ b/tests/tests/compiler/examples/basic_bank.leo @@ -47,7 +47,7 @@ program basic_bank.aleo { // Requires that the function caller is the bank. // The bank's address is aleo1t0uer3jgtsgmx5tq6x6f9ecu8tr57rzzfnc2dgmcqldceal0ls9qf6st7a. fn issue(owner: address, amount: u64) -> Token { - assert_eq(self.caller, aleo1t0uer3jgtsgmx5tq6x6f9ecu8tr57rzzfnc2dgmcqldceal0ls9qf6st7a); + assert_eq(std::ctx::caller(), aleo1t0uer3jgtsgmx5tq6x6f9ecu8tr57rzzfnc2dgmcqldceal0ls9qf6st7a); return Token { owner: owner, amount: amount }; } @@ -75,7 +75,7 @@ program basic_bank.aleo { // - `periods` : The number of periods to compound the interest over. // Requires that the function caller is the bank. fn withdraw(recipient: address, amount: u64, rate: u64, periods: u64) -> (Token, Final) { - assert_eq(self.caller, aleo1t0uer3jgtsgmx5tq6x6f9ecu8tr57rzzfnc2dgmcqldceal0ls9qf6st7a); + assert_eq(std::ctx::caller(), aleo1t0uer3jgtsgmx5tq6x6f9ecu8tr57rzzfnc2dgmcqldceal0ls9qf6st7a); let hash: field = BHP256::hash_to_field(recipient); let total: u64 = calculate_interest(amount, rate, periods); diff --git a/tests/tests/compiler/examples/board.leo b/tests/tests/compiler/examples/board.leo index 5a5e689312b..d61966277a7 100644 --- a/tests/tests/compiler/examples/board.leo +++ b/tests/tests/compiler/examples/board.leo @@ -22,11 +22,11 @@ program test.aleo { // Returns a new board_state. fn new_board_state(ships: u64, opponent: address) -> board_state { return board_state { - owner: self.signer, + owner: std::ctx::signer(), hits_and_misses: 0u64, played_tiles: 0u64, ships, - player_1: self.caller, + player_1: std::ctx::caller(), player_2: opponent, game_started: false, }; diff --git a/tests/tests/compiler/examples/lottery.leo b/tests/tests/compiler/examples/lottery.leo index 849a21855f2..8e0c10920d8 100644 --- a/tests/tests/compiler/examples/lottery.leo +++ b/tests/tests/compiler/examples/lottery.leo @@ -7,7 +7,7 @@ program lottery.aleo { mapping num_winners: u8 => u8; fn play() -> (Ticket, Final) { - let ticket: Ticket = Ticket { owner: self.signer }; + let ticket: Ticket = Ticket { owner: std::ctx::signer() }; return ( ticket, final { @@ -22,7 +22,7 @@ program lottery.aleo { final fn finalize_play() { // Check that the lottery has not expired. - assert(block.height <= 1000u32); + assert(std::ctx::block_height() <= 1000u32); // Randomly select whether or not the ticket is a winner. assert(ChaCha::rand_bool()); diff --git a/tests/tests/compiler/examples/move.leo b/tests/tests/compiler/examples/move.leo index c0105131e7b..80c42f0911e 100644 --- a/tests/tests/compiler/examples/move.leo +++ b/tests/tests/compiler/examples/move.leo @@ -35,7 +35,7 @@ program test.aleo { return move { owner: player_2, incoming_fire_coordinate: 0u64, - player_1: self.caller, + player_1: std::ctx::caller(), player_2: player_2, prev_hit_or_miss: 0u64, }; diff --git a/tests/tests/compiler/examples/token.leo b/tests/tests/compiler/examples/token.leo index 1f8cf1c8d9d..3b9cc640a42 100644 --- a/tests/tests/compiler/examples/token.leo +++ b/tests/tests/compiler/examples/token.leo @@ -62,7 +62,7 @@ program token.aleo { /* Transfer */ fn transfer_public(public receiver: address, public amount: u64) -> Final { // Transfer the tokens publicly, by invoking the computation on-chain. - let caller = self.caller; + let caller = std::ctx::caller(); return final { finalize_tr_public(caller, receiver, amount); }; } @@ -112,7 +112,7 @@ program token.aleo { let transferred: token = token { owner: receiver, amount: amount }; // Output the receiver's record. // Decrement the token amount of the caller publicly. - let caller = self.caller; + let caller = std::ctx::caller(); return ( transferred, final { diff --git a/tests/tests/compiler/examples/vote.leo b/tests/tests/compiler/examples/vote.leo index 2baaeae08fb..995e2dc8572 100644 --- a/tests/tests/compiler/examples/vote.leo +++ b/tests/tests/compiler/examples/vote.leo @@ -57,7 +57,7 @@ program vote.aleo { // Propose a new proposal to vote on. fn propose(public info: ProposalInfo) -> (Proposal, Final) { // Authenticate proposer. - assert_eq(self.signer, info.proposer); + assert_eq(std::ctx::signer(), info.proposer); // Generate a new proposal id. let id: field = BHP256::hash_to_field(info.title); @@ -65,7 +65,7 @@ program vote.aleo { // Return a new record for the proposal. // Finalize the proposal id. return ( - Proposal { owner: self.signer, id, info }, + Proposal { owner: std::ctx::signer(), id, info }, final { finalize_propose(id); }, diff --git a/tests/tests/compiler/expression/network_id.leo b/tests/tests/compiler/expression/network_id.leo index fe4ac34352c..b7bc84740d2 100644 --- a/tests/tests/compiler/expression/network_id.leo +++ b/tests/tests/compiler/expression/network_id.leo @@ -8,7 +8,7 @@ program test.aleo { } final fn finalize_main(a: u16) { - assert_eq(1u16, network.id); - assert_eq(a, network.id); - assert_eq(network.id, network.id); + assert_eq(1u16, std::ctx::network_id()); + assert_eq(a, std::ctx::network_id()); + assert_eq(std::ctx::network_id(), std::ctx::network_id()); } diff --git a/tests/tests/compiler/finalize/block_height.leo b/tests/tests/compiler/finalize/block_height.leo index 5f4e6b452c2..84dcf6e6b9e 100644 --- a/tests/tests/compiler/finalize/block_height.leo +++ b/tests/tests/compiler/finalize/block_height.leo @@ -8,5 +8,5 @@ program test.aleo { } final fn finalize_matches(height: u32) { - assert_eq(height, block.height); + assert_eq(height, std::ctx::block_height()); } diff --git a/tests/tests/compiler/finalize/block_height_fail.leo b/tests/tests/compiler/finalize/block_height_fail.leo index fa3a311adac..1e0151d31c5 100644 --- a/tests/tests/compiler/finalize/block_height_fail.leo +++ b/tests/tests/compiler/finalize/block_height_fail.leo @@ -1,6 +1,6 @@ program test.aleo { fn matches(height: u32) { - assert_eq(height, block.height); + assert_eq(height, std::ctx::block_height()); return; } diff --git a/tests/tests/compiler/finalize/block_timestamp.leo b/tests/tests/compiler/finalize/block_timestamp.leo index c32d983117c..f2e01dcccc0 100644 --- a/tests/tests/compiler/finalize/block_timestamp.leo +++ b/tests/tests/compiler/finalize/block_timestamp.leo @@ -8,5 +8,5 @@ program test.aleo { } final fn finalize_matches(timestamp: i64) { - assert_eq(timestamp, block.timestamp); + assert_eq(timestamp, std::ctx::block_timestamp()); } diff --git a/tests/tests/compiler/finalize/block_timestamp_fail.leo b/tests/tests/compiler/finalize/block_timestamp_fail.leo index 9582a845d18..19a10404530 100644 --- a/tests/tests/compiler/finalize/block_timestamp_fail.leo +++ b/tests/tests/compiler/finalize/block_timestamp_fail.leo @@ -1,6 +1,6 @@ program test.aleo { fn matches(timestamp: i64) { - assert_eq(timestamp, block.timestamp); + assert_eq(timestamp, std::ctx::block_timestamp()); return; } diff --git a/tests/tests/compiler/finalize/contains.leo b/tests/tests/compiler/finalize/contains.leo index 1c1aa921f75..3802fc387fd 100644 --- a/tests/tests/compiler/finalize/contains.leo +++ b/tests/tests/compiler/finalize/contains.leo @@ -2,7 +2,7 @@ program test.aleo { mapping balances: address => u32; fn foo() -> Final { - let caller = self.caller; + let caller = std::ctx::caller(); return final { finalize_foo(caller); }; } diff --git a/tests/tests/compiler/finalize/decrement_fail.leo b/tests/tests/compiler/finalize/decrement_fail.leo index 7890f58d850..caca13e07c9 100644 --- a/tests/tests/compiler/finalize/decrement_fail.leo +++ b/tests/tests/compiler/finalize/decrement_fail.leo @@ -2,7 +2,7 @@ program test.aleo { mapping amounts: address => u128; fn decrease_self(amount: u128) -> Final { - let caller = self.caller; + let caller = std::ctx::caller(); return final { finalize_dec(caller, amount); }; } diff --git a/tests/tests/compiler/finalize/decrement_via_get_set.leo b/tests/tests/compiler/finalize/decrement_via_get_set.leo index b2d0ae2067c..e9f91b8d7ae 100644 --- a/tests/tests/compiler/finalize/decrement_via_get_set.leo +++ b/tests/tests/compiler/finalize/decrement_via_get_set.leo @@ -2,7 +2,7 @@ program test.aleo { mapping amounts: address => u128; fn decrease_self(amount: u128) -> Final { - let caller = self.caller; + let caller = std::ctx::caller(); return final { finalize_dec(caller, amount); }; } diff --git a/tests/tests/compiler/finalize/finalize.leo b/tests/tests/compiler/finalize/finalize.leo index 02b703b7e11..eddbdfd1ccf 100644 --- a/tests/tests/compiler/finalize/finalize.leo +++ b/tests/tests/compiler/finalize/finalize.leo @@ -7,7 +7,7 @@ program test.aleo { } fn finalize_self_caller() -> Final { - let caller = self.caller; + let caller = std::ctx::caller(); return final { finalize_finalize_self_caller(caller); }; } diff --git a/tests/tests/compiler/finalize/finalize_fail.leo b/tests/tests/compiler/finalize/finalize_fail.leo index 76c38189ef6..fc9c4b02426 100644 --- a/tests/tests/compiler/finalize/finalize_fail.leo +++ b/tests/tests/compiler/finalize/finalize_fail.leo @@ -28,5 +28,5 @@ final fn finalize_public_adder(a: u8, b: u8) -> public u8 { final fn finalize_no_params() { increment(values, 0u8, 1u8); - increment(account, self.caller, 1u64); + increment(account, std::ctx::caller(), 1u64); } diff --git a/tests/tests/compiler/finalize/finalize_return_misc.leo b/tests/tests/compiler/finalize/finalize_return_misc.leo index 21b36a29346..e4da9805059 100644 --- a/tests/tests/compiler/finalize/finalize_return_misc.leo +++ b/tests/tests/compiler/finalize/finalize_return_misc.leo @@ -17,7 +17,7 @@ program test.aleo { @custom constructor() { let initial: u64 = base_supply(); - Mapping::set(account, self.address, initial); + Mapping::set(account, std::ctx::addr(), initial); } } diff --git a/tests/tests/compiler/finalize/finalize_with_method_calls.leo b/tests/tests/compiler/finalize/finalize_with_method_calls.leo index 01bfc7bafe0..cbfa2f24eed 100644 --- a/tests/tests/compiler/finalize/finalize_with_method_calls.leo +++ b/tests/tests/compiler/finalize/finalize_with_method_calls.leo @@ -7,7 +7,7 @@ program test.aleo { } fn finalize_self_caller() -> Final { - let caller = self.caller; + let caller = std::ctx::caller(); return final { finalize_finalize_self_caller(caller); }; } diff --git a/tests/tests/compiler/finalize/get_incorrect_num_operands.leo b/tests/tests/compiler/finalize/get_incorrect_num_operands.leo index 30b6ce4376c..67e30942fe4 100644 --- a/tests/tests/compiler/finalize/get_incorrect_num_operands.leo +++ b/tests/tests/compiler/finalize/get_incorrect_num_operands.leo @@ -8,7 +8,7 @@ program test.aleo { mapping tokens: address => Token; fn decrease_self(amount: u128) -> Final { - return final { finalize_decrease_self(self.caller, amount); }; + return final { finalize_decrease_self(std::ctx::caller(), amount); }; } @noupgrade diff --git a/tests/tests/compiler/finalize/get_incorrect_type_fail.leo b/tests/tests/compiler/finalize/get_incorrect_type_fail.leo index 4eec8589526..19e28e762c1 100644 --- a/tests/tests/compiler/finalize/get_incorrect_type_fail.leo +++ b/tests/tests/compiler/finalize/get_incorrect_type_fail.leo @@ -8,7 +8,7 @@ program test.aleo { mapping tokens: address => Token; fn decrease_self(amount: u128) -> Final { - let caller = self.caller; + let caller = std::ctx::caller(); return final { finalize_decrease_self(caller, amount); }; } diff --git a/tests/tests/compiler/finalize/get_or_incorrect_num_operands.leo b/tests/tests/compiler/finalize/get_or_incorrect_num_operands.leo index 58542e44a34..74669801081 100644 --- a/tests/tests/compiler/finalize/get_or_incorrect_num_operands.leo +++ b/tests/tests/compiler/finalize/get_or_incorrect_num_operands.leo @@ -8,7 +8,7 @@ program test.aleo { mapping tokens: address => Token; fn decrease_self(amount: u128) -> Final { - return final { finalize_decrease_self(self.caller, amount); }; + return final { finalize_decrease_self(std::ctx::caller(), amount); }; } @noupgrade diff --git a/tests/tests/compiler/finalize/get_or_incorrect_type_fail.leo b/tests/tests/compiler/finalize/get_or_incorrect_type_fail.leo index 719ac8fd8de..8364ef9cf5b 100644 --- a/tests/tests/compiler/finalize/get_or_incorrect_type_fail.leo +++ b/tests/tests/compiler/finalize/get_or_incorrect_type_fail.leo @@ -8,7 +8,7 @@ program test.aleo { mapping tokens: address => Token; fn decrease_self(amount: u128) -> Final { - let caller = self.caller; + let caller = std::ctx::caller(); return final { finalize_decrease_self(caller, amount); }; } diff --git a/tests/tests/compiler/finalize/increment_fail.leo b/tests/tests/compiler/finalize/increment_fail.leo index da46f49f194..1ba793b89aa 100644 --- a/tests/tests/compiler/finalize/increment_fail.leo +++ b/tests/tests/compiler/finalize/increment_fail.leo @@ -2,7 +2,7 @@ program test.aleo { mapping amounts: address => u128; fn increase_self(amount: u128) -> Final { - let caller = self.caller; + let caller = std::ctx::caller(); return final { finalize_increase_self(caller, amount); }; } diff --git a/tests/tests/compiler/finalize/increment_via_get_set.leo b/tests/tests/compiler/finalize/increment_via_get_set.leo index 1dd58b21438..ea2f0bd65ad 100644 --- a/tests/tests/compiler/finalize/increment_via_get_set.leo +++ b/tests/tests/compiler/finalize/increment_via_get_set.leo @@ -2,7 +2,7 @@ program test.aleo { mapping amounts: address => u128; fn increase_self(amount: u128) -> Final { - let caller = self.caller; + let caller = std::ctx::caller(); return final { finalize_increase_self(caller, amount); }; } diff --git a/tests/tests/compiler/finalize/mapping.leo b/tests/tests/compiler/finalize/mapping.leo index 94bfacc9fbb..899c6461006 100644 --- a/tests/tests/compiler/finalize/mapping.leo +++ b/tests/tests/compiler/finalize/mapping.leo @@ -1,6 +1,6 @@ program test.aleo { fn matches(addr: address) -> bool { - return self.caller == addr; + return std::ctx::caller() == addr; } mapping balances: address => u128; diff --git a/tests/tests/compiler/finalize/mapping_operations_in_inline_fail.leo b/tests/tests/compiler/finalize/mapping_operations_in_inline_fail.leo index e4c6d13c333..a5691643af9 100644 --- a/tests/tests/compiler/finalize/mapping_operations_in_inline_fail.leo +++ b/tests/tests/compiler/finalize/mapping_operations_in_inline_fail.leo @@ -8,13 +8,13 @@ program test.aleo { fn foo() { Mapping::set(values, 0u8, 1u8); - Mapping::get_or_use(account, self.caller, 1u64); + Mapping::get_or_use(account, std::ctx::caller(), 1u64); Mapping::get(values, 1u8); } fn bar() { Mapping::set(values, 0u8, 1u8); - Mapping::get_or_use(account, self.caller, 1u64); + Mapping::get_or_use(account, std::ctx::caller(), 1u64); Mapping::get(values, 0u8); } diff --git a/tests/tests/compiler/finalize/remove.leo b/tests/tests/compiler/finalize/remove.leo index fed988cb6c6..cf691aad247 100644 --- a/tests/tests/compiler/finalize/remove.leo +++ b/tests/tests/compiler/finalize/remove.leo @@ -2,7 +2,7 @@ program test.aleo { mapping balances: address => u32; fn foo() -> Final { - let caller = self.caller; + let caller = std::ctx::caller(); return final { finalize_foo(caller); }; } diff --git a/tests/tests/compiler/finalize/set_in_an_assignment_fail.leo b/tests/tests/compiler/finalize/set_in_an_assignment_fail.leo index 951966a79b0..4b84ce2210b 100644 --- a/tests/tests/compiler/finalize/set_in_an_assignment_fail.leo +++ b/tests/tests/compiler/finalize/set_in_an_assignment_fail.leo @@ -2,7 +2,7 @@ program test.aleo { mapping amounts: address => u128; fn decrease_self(amount: u128) -> Final { - return final { finalize_decrease_self(self.caller, amount); }; + return final { finalize_decrease_self(std::ctx::caller(), amount); }; } @noupgrade diff --git a/tests/tests/compiler/finalize/set_incorrect_num_operands.leo b/tests/tests/compiler/finalize/set_incorrect_num_operands.leo index e96f52e716c..15e47e52c75 100644 --- a/tests/tests/compiler/finalize/set_incorrect_num_operands.leo +++ b/tests/tests/compiler/finalize/set_incorrect_num_operands.leo @@ -8,7 +8,7 @@ program test.aleo { mapping tokens: address => Token; fn decrease_self(amount: u128) -> Final { - return final { finalize_decrease_self(self.caller, amount); }; + return final { finalize_decrease_self(std::ctx::caller(), amount); }; } @noupgrade diff --git a/tests/tests/compiler/finalize/set_incorrect_type_fail.leo b/tests/tests/compiler/finalize/set_incorrect_type_fail.leo index 1c86d9a62a5..c61e8604f38 100644 --- a/tests/tests/compiler/finalize/set_incorrect_type_fail.leo +++ b/tests/tests/compiler/finalize/set_incorrect_type_fail.leo @@ -8,7 +8,7 @@ program test.aleo { mapping tokens: address => Token; fn decrease_self(amount: u128) -> Final { - let caller = self.caller; + let caller = std::ctx::caller(); return final { finalize_decrease_self(caller, amount); }; } diff --git a/tests/tests/compiler/function/dead_code_elimination.leo b/tests/tests/compiler/function/dead_code_elimination.leo index e925a0c27d0..4a82a071876 100644 --- a/tests/tests/compiler/function/dead_code_elimination.leo +++ b/tests/tests/compiler/function/dead_code_elimination.leo @@ -42,7 +42,7 @@ program test.aleo { if (a == b) { e = inline_and_eliminate(a, b); } - let f: dummy = dummy { owner: self.signer, data: e }; + let f: dummy = dummy { owner: std::ctx::signer(), data: e }; return a + b; } diff --git a/tests/tests/compiler/function/program_core_functions.leo b/tests/tests/compiler/function/program_core_functions.leo index 4b4b31b0498..d7e7e75c396 100644 --- a/tests/tests/compiler/function/program_core_functions.leo +++ b/tests/tests/compiler/function/program_core_functions.leo @@ -1,12 +1,12 @@ final fn foo() { - let c: [u8; 32] = self.checksum; - let d: [u8; 32] = Program::checksum(test.aleo); - let e: u16 = self.edition; - let f: u16 = Program::edition(test.aleo); - let g: address = self.program_owner; - let h: address = Program::program_owner(test.aleo); - let i: [u8; 32] = Program::function_checksum(test.aleo, 'bar'); - let j: [u8; 32] = Program::function_checksum(test.aleo, 'peek'); + let c: [u8; 32] = std::ctx::checksum(); + let d: [u8; 32] = std::prog::checksum::[test.aleo](); + let e: u16 = std::ctx::edition(); + let f: u16 = std::prog::edition::[test.aleo](); + let g: address = std::ctx::program_owner(); + let h: address = std::prog::program_owner::[test.aleo](); + let i: [u8; 32] = std::prog::function_checksum::[test.aleo, 'bar'](); + let j: [u8; 32] = std::prog::function_checksum::[test.aleo, 'peek'](); assert_eq(c, d); assert_eq(e, f); assert_eq(g, h); diff --git a/tests/tests/compiler/function/program_core_functions_external_aleo.leo b/tests/tests/compiler/function/program_core_functions_external_aleo.leo index 72904208e18..c1361aa5053 100644 --- a/tests/tests/compiler/function/program_core_functions_external_aleo.leo +++ b/tests/tests/compiler/function/program_core_functions_external_aleo.leo @@ -23,8 +23,8 @@ import child.aleo; program parent.aleo { final fn foo() { - let i: [u8; 32] = Program::function_checksum(child.aleo, 'entry'); - let j: [u8; 32] = Program::function_checksum(child.aleo, 'peek'); + let i: [u8; 32] = std::prog::function_checksum::[child.aleo, 'entry'](); + let j: [u8; 32] = std::prog::function_checksum::[child.aleo, 'peek'](); assert_neq(i, j); } diff --git a/tests/tests/compiler/function/program_core_functions_external_leo.leo b/tests/tests/compiler/function/program_core_functions_external_leo.leo index ab7bd7a788a..4235750a808 100644 --- a/tests/tests/compiler/function/program_core_functions_external_leo.leo +++ b/tests/tests/compiler/function/program_core_functions_external_leo.leo @@ -19,8 +19,8 @@ import child.aleo; program parent.aleo { final fn foo() { - let i: [u8; 32] = Program::function_checksum(child.aleo, 'entry'); - let j: [u8; 32] = Program::function_checksum(child.aleo, 'peek'); + let i: [u8; 32] = std::prog::function_checksum::[child.aleo, 'entry'](); + let j: [u8; 32] = std::prog::function_checksum::[child.aleo, 'peek'](); assert_neq(i, j); } diff --git a/tests/tests/compiler/function/program_core_functions_fail.leo b/tests/tests/compiler/function/program_core_functions_fail.leo index cd7f35c2f2e..5f5b5e05436 100644 --- a/tests/tests/compiler/function/program_core_functions_fail.leo +++ b/tests/tests/compiler/function/program_core_functions_fail.leo @@ -1,18 +1,18 @@ final fn foo() { - let c: [u8; 32] = Program::checksum(test.aleo); - let d: [u8; 31] = Program::checksum(credits.aleo); + let c: [u8; 32] = std::prog::checksum::[test.aleo](); + let d: [u8; 31] = std::prog::checksum::[credits.aleo](); assert_neq(c, d); - let e: u16 = Program::edition(d); - let f: u8 = Program::edition(credits.aleo); + let e: u16 = std::prog::edition::[d](); + let f: u8 = std::prog::edition::[credits.aleo](); assert_neq(e, f); // The first argument must be a program ID. - let g: [u8; 32] = Program::function_checksum(d, 'bar'); + let g: [u8; 32] = std::prog::function_checksum::[d, 'bar'](); // The function name must be an identifier literal, not a string. - let h: [u8; 32] = Program::function_checksum(test.aleo, "bar"); + let h: [u8; 32] = std::prog::function_checksum::[test.aleo, "bar"](); // The function must resolve to an entry or view function; `missing` is neither. - let i: [u8; 32] = Program::function_checksum(test.aleo, 'missing'); + let i: [u8; 32] = std::prog::function_checksum::[test.aleo, 'missing'](); assert_neq(g, h); assert_neq(g, i); } diff --git a/tests/tests/compiler/function/program_core_functions_long_name_fail.leo b/tests/tests/compiler/function/program_core_functions_long_name_fail.leo index 76fdda0386a..ebe72f3305d 100644 --- a/tests/tests/compiler/function/program_core_functions_long_name_fail.leo +++ b/tests/tests/compiler/function/program_core_functions_long_name_fail.leo @@ -1,8 +1,8 @@ final fn foo() { - let c: [u8; 32] = Program::checksum(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aleo); - let d: u16 = Program::edition(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aleo); - let e: address = Program::program_owner(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aleo); + let c: [u8; 32] = std::prog::checksum::[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aleo](); + let d: u16 = std::prog::edition::[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aleo](); + let e: address = std::prog::program_owner::[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aleo](); } program test.aleo { diff --git a/tests/tests/compiler/function/self.leo b/tests/tests/compiler/function/self.leo index bb4f1bf235b..b5143e17008 100644 --- a/tests/tests/compiler/function/self.leo +++ b/tests/tests/compiler/function/self.leo @@ -1,6 +1,6 @@ program test.aleo { fn matches(addr: address) -> bool { - return self.caller == addr; + return std::ctx::caller() == addr; } @noupgrade diff --git a/tests/tests/compiler/function/self_finalize_fail.leo b/tests/tests/compiler/function/self_finalize_fail.leo index 2e8c233289f..b3329ae76f4 100644 --- a/tests/tests/compiler/function/self_finalize_fail.leo +++ b/tests/tests/compiler/function/self_finalize_fail.leo @@ -1,9 +1,9 @@ program test.aleo { fn matches(addr: address) -> (bool, Final) { return ( - self.caller == addr, + std::ctx::caller() == addr, final { - finalize_matches(self.caller); + finalize_matches(std::ctx::caller()); }, ); } @@ -13,5 +13,5 @@ program test.aleo { } final fn finalize_matches(addr: address) { - assert_eq(addr, self.caller); + assert_eq(addr, std::ctx::caller()); } diff --git a/tests/tests/compiler/futures/future_access_tuple_fail.leo b/tests/tests/compiler/futures/future_access_tuple_fail.leo index 0d9ce451519..1048ae4764e 100644 --- a/tests/tests/compiler/futures/future_access_tuple_fail.leo +++ b/tests/tests/compiler/futures/future_access_tuple_fail.leo @@ -24,7 +24,7 @@ program test_credits.aleo { fn send_credits(input: credits.aleo::credits, amount: u64) -> (credits.aleo::credits, Final) { let start: (credits.aleo::credits, Final) = credits.aleo::transfer_private_to_public( input, - self.address, + std::ctx::addr(), amount, ); let after: (u8, credits.aleo::credits) = (1u8, start.0); diff --git a/tests/tests/compiler/futures/future_in_tuple.leo b/tests/tests/compiler/futures/future_in_tuple.leo index e1d553bbdde..7cc89790fbc 100644 --- a/tests/tests/compiler/futures/future_in_tuple.leo +++ b/tests/tests/compiler/futures/future_in_tuple.leo @@ -24,7 +24,7 @@ program test_credits.aleo { fn send_credits(input: credits.aleo::credits, amount: u64) -> (credits.aleo::credits, Final) { let result: (credits.aleo::credits, Final) = credits.aleo::transfer_private_to_public( input, - self.address, + std::ctx::addr(), amount, ); return ( diff --git a/tests/tests/compiler/futures/future_in_tuple_check_fail.leo b/tests/tests/compiler/futures/future_in_tuple_check_fail.leo index d48bd6fec3a..351081ead57 100644 --- a/tests/tests/compiler/futures/future_in_tuple_check_fail.leo +++ b/tests/tests/compiler/futures/future_in_tuple_check_fail.leo @@ -24,12 +24,12 @@ program test_credits.aleo { fn send_credits(input: credits.aleo::credits, amount: u64) -> (credits.aleo::credits, Final) { let result: (credits.aleo::credits, Final) = credits.aleo::transfer_private_to_public( input, - self.address, + std::ctx::addr(), amount, ); let result2: (credits.aleo::credits, Final) = credits.aleo::transfer_private_to_public( input, - self.address, + std::ctx::addr(), amount, ); return ( diff --git a/tests/tests/compiler/futures/future_not_all_awaited_fail.leo b/tests/tests/compiler/futures/future_not_all_awaited_fail.leo index 7e9da9491c6..0f361765f15 100644 --- a/tests/tests/compiler/futures/future_not_all_awaited_fail.leo +++ b/tests/tests/compiler/futures/future_not_all_awaited_fail.leo @@ -2,12 +2,12 @@ program child.aleo { mapping count: address => field; fn foo() -> Final { - let caller = self.caller; + let caller = std::ctx::caller(); return final { finalize_foo(caller); }; } fn boo() -> Final { - let caller = self.caller; + let caller = std::ctx::caller(); return final { finalize_boo(caller); }; } diff --git a/tests/tests/compiler/futures/future_not_all_passed_to_async_call_fail.leo b/tests/tests/compiler/futures/future_not_all_passed_to_async_call_fail.leo index 2c70da651a9..de70fd96796 100644 --- a/tests/tests/compiler/futures/future_not_all_passed_to_async_call_fail.leo +++ b/tests/tests/compiler/futures/future_not_all_passed_to_async_call_fail.leo @@ -12,12 +12,12 @@ program child.aleo { mapping count: address => field; fn foo() -> Final { - let caller = self.caller; + let caller = std::ctx::caller(); return final { finalize_foo(caller); }; } fn boo() -> Final { - let caller = self.caller; + let caller = std::ctx::caller(); return final { finalize_boo(caller); }; } diff --git a/tests/tests/compiler/futures/future_type_inference.leo b/tests/tests/compiler/futures/future_type_inference.leo index 55c7c6ece92..6ff653b8670 100644 --- a/tests/tests/compiler/futures/future_type_inference.leo +++ b/tests/tests/compiler/futures/future_type_inference.leo @@ -27,7 +27,7 @@ program multi_token_support_program.aleo { fn mint_private() -> (Token, Final) { let f: Final = final { finalize(); }; - return (Token { owner: self.signer, amount: 100u64 }, f); + return (Token { owner: std::ctx::signer(), amount: 100u64 }, f); } @noupgrade @@ -49,7 +49,7 @@ program mtsp_credits.aleo { ) -> (credits.aleo::credits, multi_token_support_program.aleo::Token, Final) { let transfer_output: (credits.aleo::credits, Final) = credits.aleo::transfer_private_to_public( input_record, - self.address, + std::ctx::addr(), amount, ); let mint_output: (multi_token_support_program.aleo::Token, Final) = multi_token_support_program.aleo::mint_private(); diff --git a/tests/tests/compiler/futures/nested.leo b/tests/tests/compiler/futures/nested.leo index 4478ef240b5..46cbcc0afb8 100644 --- a/tests/tests/compiler/futures/nested.leo +++ b/tests/tests/compiler/futures/nested.leo @@ -9,7 +9,7 @@ program test_dep.aleo { fn main_dep(a: u32) -> (yeets, Final) { let f: Final = final { finalize_main_dep(a, 1u32); }; - let l: yeets = yeets { owner: self.signer, val: 1u32 }; + let l: yeets = yeets { owner: std::ctx::signer(), val: 1u32 }; return (l, f); } diff --git a/tests/tests/compiler/futures/partial_type_specification.leo b/tests/tests/compiler/futures/partial_type_specification.leo index 91745aa6050..d3e6bc341d0 100644 --- a/tests/tests/compiler/futures/partial_type_specification.leo +++ b/tests/tests/compiler/futures/partial_type_specification.leo @@ -10,13 +10,13 @@ program test_dep.aleo { fn main_dep(a: u32) -> (yeets, Final) { let f: Final = final { finalize_main_dep(a, 1u32); }; - let l: yeets = yeets { owner: self.signer, val: 1u32 }; + let l: yeets = yeets { owner: std::ctx::signer(), val: 1u32 }; return (l, f); } fn main_dep_2(a: u32) -> (yeets, Final) { let f: Final = final { finalize_main_dep_2(); }; - let l: yeets = yeets { owner: self.signer, val: 1u32 }; + let l: yeets = yeets { owner: std::ctx::signer(), val: 1u32 }; return (l, f); } diff --git a/tests/tests/compiler/interfaces/simple.leo b/tests/tests/compiler/interfaces/simple.leo index ee1d926e2b8..5d6202556b5 100644 --- a/tests/tests/compiler/interfaces/simple.leo +++ b/tests/tests/compiler/interfaces/simple.leo @@ -17,7 +17,7 @@ program scratch.aleo: AbstractFoo { } fn foobar() -> Foo { - return Foo { owner: self.signer, num: 42 }; + return Foo { owner: std::ctx::signer(), num: 42 }; } @noupgrade diff --git a/tests/tests/compiler/mappings/external_read_with_local.leo b/tests/tests/compiler/mappings/external_read_with_local.leo index cd29c7be827..0bcefad35a1 100644 --- a/tests/tests/compiler/mappings/external_read_with_local.leo +++ b/tests/tests/compiler/mappings/external_read_with_local.leo @@ -2,7 +2,7 @@ program registry.aleo { mapping users: address => bool; fn register() -> Final { - let caller = self.caller; + let caller = std::ctx::caller(); return final { finalize_register(caller); }; } diff --git a/tests/tests/compiler/mappings/no_import_external_read_fail.leo b/tests/tests/compiler/mappings/no_import_external_read_fail.leo index bbea47d0db0..c035f284343 100644 --- a/tests/tests/compiler/mappings/no_import_external_read_fail.leo +++ b/tests/tests/compiler/mappings/no_import_external_read_fail.leo @@ -2,7 +2,7 @@ program registry.aleo { mapping users: address => bool; fn register() -> Final { - let caller = self.caller; + let caller = std::ctx::caller(); return final { finalize_register(caller); }; } diff --git a/tests/tests/compiler/mappings/read_external_mapping.leo b/tests/tests/compiler/mappings/read_external_mapping.leo index 638ea024fd8..ebcc0a83f88 100644 --- a/tests/tests/compiler/mappings/read_external_mapping.leo +++ b/tests/tests/compiler/mappings/read_external_mapping.leo @@ -2,12 +2,12 @@ program registry.aleo { mapping users: address => bool; fn register() -> Final { - let caller = self.caller; + let caller = std::ctx::caller(); return final { finalize_register(caller); }; } fn unregister() -> Final { - let caller = self.caller; + let caller = std::ctx::caller(); return final { finalize_unregister(caller); }; } diff --git a/tests/tests/compiler/mappings/unknown_external_mapping_fail.leo b/tests/tests/compiler/mappings/unknown_external_mapping_fail.leo index 2c055f8f847..b06ec703280 100644 --- a/tests/tests/compiler/mappings/unknown_external_mapping_fail.leo +++ b/tests/tests/compiler/mappings/unknown_external_mapping_fail.leo @@ -2,7 +2,7 @@ program registry.aleo { mapping users: address => bool; fn register() -> Final { - let caller = self.caller; + let caller = std::ctx::caller(); return final { finalize_register(caller); }; } diff --git a/tests/tests/compiler/option/optional_record_fail.leo b/tests/tests/compiler/option/optional_record_fail.leo index c6872e4d7fc..f5de059a6d3 100644 --- a/tests/tests/compiler/option/optional_record_fail.leo +++ b/tests/tests/compiler/option/optional_record_fail.leo @@ -6,7 +6,7 @@ program optional_record_test.aleo { } fn handle_optional_record() -> u64 { - let f: Foo? = Foo { owner: self.signer, val: 5 }; + let f: Foo? = Foo { owner: std::ctx::signer(), val: 5 }; return 0; } diff --git a/tests/tests/compiler/records/gates_is_allowed.leo b/tests/tests/compiler/records/gates_is_allowed.leo index 9d888578236..fb01c8a26b1 100644 --- a/tests/tests/compiler/records/gates_is_allowed.leo +++ b/tests/tests/compiler/records/gates_is_allowed.leo @@ -9,7 +9,7 @@ program test.aleo { } fn main(a: u64, b: u64) -> Token { - return Token { owner: self.signer, amount: a, gates: b }; + return Token { owner: std::ctx::signer(), amount: a, gates: b }; } @noupgrade diff --git a/tests/tests/compiler/records/nested_record_as_function_io.leo b/tests/tests/compiler/records/nested_record_as_function_io.leo index 52802bde1ba..d77bc7cf591 100644 --- a/tests/tests/compiler/records/nested_record_as_function_io.leo +++ b/tests/tests/compiler/records/nested_record_as_function_io.leo @@ -5,7 +5,7 @@ program program_a.aleo { } fn mint2(input: u32) -> X { - return X { owner: self.signer, val: input }; + return X { owner: std::ctx::signer(), val: input }; } @noupgrade diff --git a/tests/tests/compiler/records/record_declaration_out_of_order.leo b/tests/tests/compiler/records/record_declaration_out_of_order.leo index 7a6c28ca446..b5224ea8c46 100644 --- a/tests/tests/compiler/records/record_declaration_out_of_order.leo +++ b/tests/tests/compiler/records/record_declaration_out_of_order.leo @@ -7,7 +7,7 @@ program test.aleo { } fn main(a: u64, b: u64) -> Token { - return Token { amount: a + b, owner: self.signer }; + return Token { amount: a + b, owner: std::ctx::signer() }; } @noupgrade diff --git a/tests/tests/compiler/records/record_with_visibility.leo b/tests/tests/compiler/records/record_with_visibility.leo index bd0764a3b30..eaada8c2bc3 100644 --- a/tests/tests/compiler/records/record_with_visibility.leo +++ b/tests/tests/compiler/records/record_with_visibility.leo @@ -9,7 +9,7 @@ program test.aleo { } fn main(a: u64, b: u64) -> Token { - return Token { amount: a + b, owner: self.signer, flag: true }; + return Token { amount: a + b, owner: std::ctx::signer(), flag: true }; } @noupgrade diff --git a/tests/tests/compiler/records/return_record_instead_of_unit_fail.leo b/tests/tests/compiler/records/return_record_instead_of_unit_fail.leo index 12c8ea65e40..b14ea47ad47 100644 --- a/tests/tests/compiler/records/return_record_instead_of_unit_fail.leo +++ b/tests/tests/compiler/records/return_record_instead_of_unit_fail.leo @@ -5,7 +5,7 @@ program test.aleo { } fn mint_credits(to: address, amount: u64) { - return test_credits { owner: self.signer, amount }; + return test_credits { owner: std::ctx::signer(), amount }; } @noupgrade diff --git a/tests/tests/compiler/records/same_name_diff_type_fail.leo b/tests/tests/compiler/records/same_name_diff_type_fail.leo index c34ba60a1c8..e16d752f74e 100644 --- a/tests/tests/compiler/records/same_name_diff_type_fail.leo +++ b/tests/tests/compiler/records/same_name_diff_type_fail.leo @@ -5,7 +5,7 @@ program child.aleo { } fn create() -> R { - return R { owner: self.signer, x: 1u8 }; + return R { owner: std::ctx::signer(), x: 1u8 }; } @noupgrade @@ -22,7 +22,7 @@ program parent.aleo { } fn check() -> bool { - let r1: R = R { owner: self.signer, x: 1u16 }; + let r1: R = R { owner: std::ctx::signer(), x: 1u16 }; return r1 == child.aleo::create(); } diff --git a/tests/tests/compiler/records/self_caller_as_record_owner.leo b/tests/tests/compiler/records/self_caller_as_record_owner.leo index 435d7d08f27..e910e4dd447 100644 --- a/tests/tests/compiler/records/self_caller_as_record_owner.leo +++ b/tests/tests/compiler/records/self_caller_as_record_owner.leo @@ -4,11 +4,11 @@ program test0.aleo { } fn foo() -> Token { - return Token { owner: self.caller }; + return Token { owner: std::ctx::caller() }; } fn bar() -> Token { - let t: Token = Token { owner: self.caller }; + let t: Token = Token { owner: std::ctx::caller() }; return t; } diff --git a/tests/tests/compiler/return/external_record.leo b/tests/tests/compiler/return/external_record.leo index a688dd9acc0..53beeed8958 100644 --- a/tests/tests/compiler/return/external_record.leo +++ b/tests/tests/compiler/return/external_record.leo @@ -4,7 +4,7 @@ program test0.aleo { } fn foo() -> R { - return R { owner: self.signer }; + return R { owner: std::ctx::signer() }; } @noupgrade diff --git a/tests/tests/compiler/statements/assign_external_record_fail.leo b/tests/tests/compiler/statements/assign_external_record_fail.leo index 86a94d93cfe..3c163b4ea3d 100644 --- a/tests/tests/compiler/statements/assign_external_record_fail.leo +++ b/tests/tests/compiler/statements/assign_external_record_fail.leo @@ -5,7 +5,7 @@ program test0.aleo { } fn foo() -> R { - return R { owner: self.signer, x: true }; + return R { owner: std::ctx::signer(), x: true }; } @noupgrade diff --git a/tests/tests/compiler/structs/external_record.leo b/tests/tests/compiler/structs/external_record.leo index a4ec5c90ea9..852eccb168f 100644 --- a/tests/tests/compiler/structs/external_record.leo +++ b/tests/tests/compiler/structs/external_record.leo @@ -22,7 +22,7 @@ program parent.aleo { } fn wrapper_mint(owner: address, val: u32) -> (child.aleo::A, B) { - return (child.aleo::mint(self.caller, 1u32), B { owner: self.signer, val: val }); + return (child.aleo::mint(std::ctx::caller(), 1u32), B { owner: std::ctx::signer(), val: val }); } @noupgrade diff --git a/tests/tests/compiler/structs/external_struct_2.leo b/tests/tests/compiler/structs/external_struct_2.leo index 65a176791e0..309783b186c 100644 --- a/tests/tests/compiler/structs/external_struct_2.leo +++ b/tests/tests/compiler/structs/external_struct_2.leo @@ -51,7 +51,7 @@ program child.aleo { }, ], }, - Boo { owner: self.signer, val: 10u32 }, + Boo { owner: std::ctx::signer(), val: 10u32 }, ); } @@ -132,7 +132,7 @@ program parent.aleo { return ( f1, b1, BooHoo { - owner: self.signer, + owner: std::ctx::signer(), val: 10u32, woo: Woo { a: 1u32, b: 2u32 }, }, diff --git a/tests/tests/compiler/ternary/external_record_fail.leo b/tests/tests/compiler/ternary/external_record_fail.leo index 11d49bd94f8..164bf5dff62 100644 --- a/tests/tests/compiler/ternary/external_record_fail.leo +++ b/tests/tests/compiler/ternary/external_record_fail.leo @@ -5,7 +5,7 @@ program test0.aleo { } fn foo() -> R { - return R { owner: self.signer, x: true }; + return R { owner: std::ctx::signer(), x: true }; } @noupgrade diff --git a/tests/tests/compiler/view/view_reads_block_timestamp_fail.leo b/tests/tests/compiler/view/view_reads_block_timestamp_fail.leo index e86dc8c8886..3faa57ea033 100644 --- a/tests/tests/compiler/view/view_reads_block_timestamp_fail.leo +++ b/tests/tests/compiler/view/view_reads_block_timestamp_fail.leo @@ -1,11 +1,10 @@ -// FAIL: `view fn`s execute off-consensus, so `block.timestamp` is not in scope (snarkVM fills -// it with `None` for view evaluations because there is no transaction-time semantic for an -// off-consensus read). `block.height` and `network.id` are still allowed inside views. +// FAIL: `view fn`s execute off-consensus, so `std::ctx::block_timestamp()` is not available. +// `std::ctx::block_height()` and `std::ctx::network_id()` are still allowed inside views. program test.aleo { fn dummy(x: u32) -> u32 { return x; } view fn read_time() -> i64 { - return block.timestamp; + return std::ctx::block_timestamp(); } @noupgrade diff --git a/tests/tests/execution/complex_async_blocks.leo b/tests/tests/execution/complex_async_blocks.leo index bd3d3906a61..8e5c49ea3e0 100644 --- a/tests/tests/execution/complex_async_blocks.leo +++ b/tests/tests/execution/complex_async_blocks.leo @@ -26,7 +26,7 @@ program zero_program.aleo { mapping counts: address => u64; fn c() -> Final { - let addr = self.signer; + let addr = std::ctx::signer(); let f = final { let count: u64 = counts.get_or_use(addr, 0u64); counts.set(addr, count + 1u64); @@ -44,7 +44,7 @@ program one_program.aleo { mapping counts: address => u64; fn d() -> Final { - let addr = self.signer; + let addr = std::ctx::signer(); let f = final { let count: u64 = counts.get_or_use(addr, 0u64); counts.set(addr, count + 1u64); @@ -66,7 +66,7 @@ program two_program.aleo { fn b() -> Final { let f0: Final = zero_program.aleo::c(); let f1: Final = one_program.aleo::d(); - let addr = self.signer; + let addr = std::ctx::signer(); return final { f0.run(); f1.run(); @@ -91,7 +91,7 @@ program three_program.aleo { let f0: Final = two_program.aleo::b(); let f1: Final = one_program.aleo::d(); let f2: Final = zero_program.aleo::c(); - let addr = self.signer; + let addr = std::ctx::signer(); return final { f0.run(); f1.run(); @@ -115,7 +115,7 @@ program four_program.aleo { fn a() -> Final { let f0: Final = two_program.aleo::b(); let f1: Final = three_program.aleo::e(); - let addr = self.signer; + let addr = std::ctx::signer(); return final { f0.run(); f1.run(); diff --git a/tests/tests/execution/complex_finalization.leo b/tests/tests/execution/complex_finalization.leo index 18666835b3d..626675af05b 100644 --- a/tests/tests/execution/complex_finalization.leo +++ b/tests/tests/execution/complex_finalization.leo @@ -31,7 +31,7 @@ program zero_program.aleo { mapping counts: address => u64; fn c() -> Final { - let signer = self.signer; + let signer = std::ctx::signer(); return final { finalize_c(signer); }; } @@ -50,7 +50,7 @@ program one_program.aleo { mapping counts: address => u64; fn d() -> Final { - let signer = self.signer; + let signer = std::ctx::signer(); return final { finalize_d(signer); }; } @@ -75,7 +75,7 @@ program two_program.aleo { fn b() -> Final { let f0: Final = zero_program.aleo::c(); let f1: Final = one_program.aleo::d(); - let signer = self.signer; + let signer = std::ctx::signer(); return final { finalize_b(f0, f1, signer); }; } @@ -103,7 +103,7 @@ program three_program.aleo { let f0: Final = two_program.aleo::b(); let f1: Final = one_program.aleo::d(); let f2: Final = zero_program.aleo::c(); - let signer = self.signer; + let signer = std::ctx::signer(); return final { finalize_e(f0, f1, f2, signer); }; } @@ -128,7 +128,7 @@ program four_program.aleo { fn a() -> Final { let f0: Final = two_program.aleo::b(); let f1: Final = three_program.aleo::e(); - let signer = self.signer; + let signer = std::ctx::signer(); return final { finalize_a(f0, f1, signer); }; } diff --git a/tests/tests/execution/counter.leo b/tests/tests/execution/counter.leo index a243e438908..4186d75bbd6 100644 --- a/tests/tests/execution/counter.leo +++ b/tests/tests/execution/counter.leo @@ -46,12 +46,12 @@ program test.aleo { mapping counter: address => u64; fn dubble() -> Final { - let caller = self.caller; + let caller = std::ctx::caller(); return final { finalize_dubble(caller); }; } fn unsafe_increment() -> Final { - let caller = self.caller; + let caller = std::ctx::caller(); return final { finalize_unsafe_increment(caller); }; } diff --git a/tests/tests/execution/counter_async_block.leo b/tests/tests/execution/counter_async_block.leo index cdc8f045608..e7fefb7ed03 100644 --- a/tests/tests/execution/counter_async_block.leo +++ b/tests/tests/execution/counter_async_block.leo @@ -30,7 +30,7 @@ program test.aleo { mapping counter: address => u64; fn dubble() -> Final { - let addr = self.caller; + let addr = std::ctx::caller(); let f = final { const BIG: u64 = 234u64; let current_value: u64 = Mapping::get_or_use(counter, addr, 0_0u64 + BIG + SMALL); @@ -43,7 +43,7 @@ program test.aleo { } fn unsafe_increment() -> Final { - let addr = self.caller; + let addr = std::ctx::caller(); return final { let current_value: u64 = Mapping::get(counter, addr); for i: u64 in SMALL..10u64 { diff --git a/tests/tests/execution/dynamic_call_record_interface.leo b/tests/tests/execution/dynamic_call_record_interface.leo index dc5c8b00bf6..0e5d79b513a 100644 --- a/tests/tests/execution/dynamic_call_record_interface.leo +++ b/tests/tests/execution/dynamic_call_record_interface.leo @@ -24,7 +24,7 @@ program vault.aleo: TokenOps { // Mints a token owned by the transaction signer. fn mint(balance: u64) -> Token { - return Token { owner: self.signer, balance }; + return Token { owner: std::ctx::signer(), balance }; } @noupgrade diff --git a/tests/tests/execution/dynamic_dispatch_intrinsic_record.leo b/tests/tests/execution/dynamic_dispatch_intrinsic_record.leo index 4fa138fd4f8..d27c036b24f 100644 --- a/tests/tests/execution/dynamic_dispatch_intrinsic_record.leo +++ b/tests/tests/execution/dynamic_dispatch_intrinsic_record.leo @@ -18,7 +18,7 @@ program a.aleo { } fn get_initial(balance: u64) -> Token { - return Token { owner: self.signer, balance }; + return Token { owner: std::ctx::signer(), balance }; } @noupgrade diff --git a/tests/tests/execution/external_struct.leo b/tests/tests/execution/external_struct.leo index 95c8a205ae9..922626e0c11 100644 --- a/tests/tests/execution/external_struct.leo +++ b/tests/tests/execution/external_struct.leo @@ -67,7 +67,7 @@ program child.aleo { }, ], }, - Boo { owner: self.signer, val: 10u32 }, + Boo { owner: std::ctx::signer(), val: 10u32 }, ); } } @@ -148,7 +148,7 @@ program parent.aleo { return ( f1, b1, BooHoo { - owner: self.signer, + owner: std::ctx::signer(), val: 10u32, woo: Woo { a: 1u32, b: 2u32 }, }, diff --git a/tests/tests/execution/metadata.leo b/tests/tests/execution/metadata.leo index 6d25ae34c1a..3035ba62a62 100644 --- a/tests/tests/execution/metadata.leo +++ b/tests/tests/execution/metadata.leo @@ -37,11 +37,11 @@ input = ["3u16"] */ final fn finalize_is_block_height(block_height: u32) { - assert_eq(block_height, block.height); + assert_eq(block_height, std::ctx::block_height()); } final fn finalize_is_network_id(network_id: u16) { - assert_eq(network_id, network.id); + assert_eq(network_id, std::ctx::network_id()); } program metadata.aleo { diff --git a/tests/tests/execution/program_core_functions.leo b/tests/tests/execution/program_core_functions.leo index 45ac1dc86be..389a220b074 100644 --- a/tests/tests/execution/program_core_functions.leo +++ b/tests/tests/execution/program_core_functions.leo @@ -20,20 +20,20 @@ import child.aleo; program test.aleo { fn bar() -> Final { return final { - let c: [u8; 32] = self.checksum; - let d: [u8; 32] = Program::checksum(child.aleo); + let c: [u8; 32] = std::ctx::checksum(); + let d: [u8; 32] = std::prog::checksum::[child.aleo](); assert_neq(c, d); - let e: u16 = Program::edition(test.aleo); - let f: u16 = Program::edition(child.aleo); + let e: u16 = std::prog::edition::[test.aleo](); + let f: u16 = std::prog::edition::[child.aleo](); assert_eq(e, f); - let g: address = Program::program_owner(test.aleo); - let h: address = Program::program_owner(child.aleo); + let g: address = std::prog::program_owner::[test.aleo](); + let h: address = std::prog::program_owner::[child.aleo](); assert_eq(g, h); - let i: [u8; 32] = Program::function_checksum(test.aleo, 'bar'); - let j: [u8; 32] = Program::function_checksum(child.aleo, 'dummy'); + let i: [u8; 32] = std::prog::function_checksum::[test.aleo, 'bar'](); + let j: [u8; 32] = std::prog::function_checksum::[child.aleo, 'dummy'](); assert_neq(i, j); }; } diff --git a/tests/tests/execution/record_and_duplicate_outputs.leo b/tests/tests/execution/record_and_duplicate_outputs.leo index 462c87e729f..e74319f872a 100644 --- a/tests/tests/execution/record_and_duplicate_outputs.leo +++ b/tests/tests/execution/record_and_duplicate_outputs.leo @@ -30,7 +30,7 @@ program test0.aleo { } fn make() -> R { - return R { owner: self.signer, x: 0field }; + return R { owner: std::ctx::signer(), x: 0field }; } @noupgrade diff --git a/tests/tests/execution/record_update.leo b/tests/tests/execution/record_update.leo index 65cbcc12b9c..3056a50b290 100644 --- a/tests/tests/execution/record_update.leo +++ b/tests/tests/execution/record_update.leo @@ -21,7 +21,7 @@ program test.aleo { // Build a base record from the signer, then derive a new record that copies // `owner` and `nonce` from the base while overriding only `amount`. fn make_and_update(new_amount: u64) -> (Token, Token) { - let base: Token = Token { owner: self.signer, amount: 100u64, nonce: 7u64 }; + let base: Token = Token { owner: std::ctx::signer(), amount: 100u64, nonce: 7u64 }; let updated: Token = Token { amount: new_amount, ..base }; return (base, updated); } diff --git a/tests/tests/execution/repeat_in_loop.leo b/tests/tests/execution/repeat_in_loop.leo index 1c4e9378d50..ac772675663 100644 --- a/tests/tests/execution/repeat_in_loop.leo +++ b/tests/tests/execution/repeat_in_loop.leo @@ -35,6 +35,6 @@ program test.aleo { @custom constructor() { - assert_eq(self.edition, 0u16); + assert_eq(std::ctx::edition(), 0u16); } } diff --git a/tests/tests/execution/serialize_deserialize_roundtrip_async.leo b/tests/tests/execution/serialize_deserialize_roundtrip_async.leo index 3c8c8a75de8..ae1ca895328 100644 --- a/tests/tests/execution/serialize_deserialize_roundtrip_async.leo +++ b/tests/tests/execution/serialize_deserialize_roundtrip_async.leo @@ -57,17 +57,17 @@ final fn fin_test_async_array_rt(addr: address, value: [u8; 2]) { program test.aleo { fn test_async_u32_rt(value: u32) -> Final { - let caller = self.caller; + let caller = std::ctx::caller(); return final { fin_test_async_u32_rt(caller, value); }; } fn test_async_field_rt(value: field) -> Final { - let caller = self.caller; + let caller = std::ctx::caller(); return final { fin_test_async_field_rt(caller, value); }; } fn test_async_array_rt(value: [u8; 2]) -> Final { - let caller = self.caller; + let caller = std::ctx::caller(); return final { fin_test_async_array_rt(caller, value); }; } diff --git a/tests/tests/execution/test_test_framework.leo b/tests/tests/execution/test_test_framework.leo index 4cf93e21835..65ae45a1d84 100644 --- a/tests/tests/execution/test_test_framework.leo +++ b/tests/tests/execution/test_test_framework.leo @@ -11,7 +11,7 @@ input = ["23u32"] // Note the input height is 23, since the test framework creates a few more blocks to set up the VM. final fn check_starting_height_(height: u32) { - assert(height <= block.height); + assert(height <= std::ctx::block_height()); } program test.aleo { diff --git a/tests/tests/parser-expression/expression/ident.leo b/tests/tests/parser-expression/expression/ident.leo index b90dc44a005..bb5a1006c1d 100644 --- a/tests/tests/parser-expression/expression/ident.leo +++ b/tests/tests/parser-expression/expression/ident.leo @@ -25,8 +25,6 @@ constX test_test -Self - input selfX diff --git a/tests/tests/parser-expression/expression/path.leo b/tests/tests/parser-expression/expression/path.leo index 7e1afe8ec30..c8af93cf393 100644 --- a/tests/tests/parser-expression/expression/path.leo +++ b/tests/tests/parser-expression/expression/path.leo @@ -7,10 +7,10 @@ xxx::xxx XXX::YYY::ZZZ -Self::pp::qq - foo.aleo::bar foo/bar +Self::pp::qq + self::y diff --git a/tests/tests/parser-statement/statement/iteration.leo b/tests/tests/parser-statement/statement/iteration.leo index 2f48a0a31c7..14e2181a816 100644 --- a/tests/tests/parser-statement/statement/iteration.leo +++ b/tests/tests/parser-statement/statement/iteration.leo @@ -9,7 +9,7 @@ for x: field in 0field..99u8 { return 1u8; } -for x: bool in 0u8..Self { +for x: bool in 0u8..Foo { return 1u8; } @@ -23,6 +23,6 @@ for x in 0field..99u8 { return 1u8; } -for x in 0u8..Self { +for x in 0u8..Foo { return 1u8; } diff --git a/tests/tests/parser/program/network_id.leo b/tests/tests/parser/program/network_id.leo index e7833566a9a..37ee575118c 100644 --- a/tests/tests/parser/program/network_id.leo +++ b/tests/tests/parser/program/network_id.leo @@ -1,6 +1,6 @@ program test.aleo {} fn main(a: address) { - assert_eq(network.id, 1u32); + assert_eq(std::ctx::network_id(), 1u32); return a; } diff --git a/tests/tests/parser/program/removed_self_block_network_sugar_fail.leo b/tests/tests/parser/program/removed_self_block_network_sugar_fail.leo new file mode 100644 index 00000000000..a616810d6b9 --- /dev/null +++ b/tests/tests/parser/program/removed_self_block_network_sugar_fail.leo @@ -0,0 +1,44 @@ +program test.aleo { + fn caller_sugar() -> address { + return self.caller; + } + fn signer_sugar() -> address { + return self.signer; + } + fn address_sugar() -> address { + return self.address; + } + fn id_sugar() -> address { + return self.id; + } + fn checksum_sugar() -> [u8; 32] { + return self.checksum; + } + fn edition_sugar() -> u16 { + return self.edition; + } + fn owner_sugar() -> address { + return self.program_owner; + } + final fn block_height_sugar() -> u32 { + return block.height; + } + final fn block_timestamp_sugar() -> i64 { + return block.timestamp; + } + final fn network_id_sugar() -> u16 { + return network.id; + } + fn bare_self() { + let s = self; + return; + } + fn bare_block() { + let b = block; + return; + } + fn bare_network() { + let n = network; + return; + } +} diff --git a/tests/tests/parser/program/reserved_self_upper_fail.leo b/tests/tests/parser/program/reserved_self_upper_fail.leo new file mode 100644 index 00000000000..50650bdfa90 --- /dev/null +++ b/tests/tests/parser/program/reserved_self_upper_fail.leo @@ -0,0 +1,11 @@ +program test.aleo { + fn path_use() -> u32 { + return Self::ctx::caller(); + } + fn binding_use(Self: u32) -> u32 { + return Self; + } + struct Self { + x: u32, + } +} diff --git a/tests/tests/parser/program/special_address.leo b/tests/tests/parser/program/special_address.leo index 416f6070eea..f6e701e622e 100644 --- a/tests/tests/parser/program/special_address.leo +++ b/tests/tests/parser/program/special_address.leo @@ -2,8 +2,8 @@ program test.aleo { mapping Yo: address => u32; fn main(a: address) { - assert_eq(a, self.caller); - assert_eq(a, self.address); + assert_eq(a, std::ctx::caller()); + assert_eq(a, std::ctx::addr()); assert_eq(a, hello.aleo); return foo.aleo; }