Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .circleci/lottery/src/main.leo
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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());
Expand Down
4 changes: 2 additions & 2 deletions .circleci/token/src/main.leo
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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);
},
);
}
Expand Down
4 changes: 0 additions & 4 deletions crates/ast/src/functions/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
21 changes: 16 additions & 5 deletions crates/compiler/src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Symbol> = 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(())
}
Expand Down Expand Up @@ -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",
);
Expand Down
1 change: 1 addition & 0 deletions crates/fmt/tests/harness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
10 changes: 5 additions & 5 deletions crates/fmt/tests/source/expr_method_chain.leo
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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 ,
Expand Down
2 changes: 1 addition & 1 deletion crates/fmt/tests/source/record_basic.leo
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 5 additions & 5 deletions crates/fmt/tests/target/expr_method_chain.leo
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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); };
}
}
2 changes: 1 addition & 1 deletion crates/fmt/tests/target/record_basic.leo
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
5 changes: 4 additions & 1 deletion crates/leo-std/src/leo/ctx.leo
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,24 @@ 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();
}

// 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();
}

// 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();
}

Expand Down
43 changes: 43 additions & 0 deletions crates/leo-std/src/leo/prog.leo
Original file line number Diff line number Diff line change
@@ -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);
}
2 changes: 2 additions & 0 deletions crates/leo-std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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),
]
}

Expand Down
8 changes: 4 additions & 4 deletions crates/leo/src/cli/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
}
Expand All @@ -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,
};
}
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions crates/parser-rowan/src/lexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
12 changes: 11 additions & 1 deletion crates/parser-rowan/src/parser/expressions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down Expand Up @@ -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<CompletedMarker> {
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<CompletedMarker> {
let m = self.start();
Expand Down
7 changes: 7 additions & 0 deletions crates/parser-rowan/src/syntax_kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,8 @@ define_syntax_kinds! {
KW_AS,
/// `self`
KW_SELF,
/// `Self`
KW_SELF_UPPER,
/// `assert`
KW_ASSERT,
/// `assert_eq`
Expand Down Expand Up @@ -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`
Expand Down Expand Up @@ -651,6 +655,7 @@ impl SyntaxKind {
| KW_PRIVATE
| KW_AS
| KW_SELF
| KW_SELF_UPPER
| KW_ASSERT
| KW_ASSERT_EQ
| KW_ASSERT_NEQ
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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'",
Expand Down
18 changes: 18 additions & 0 deletions crates/parser/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Loading
Loading