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
2 changes: 2 additions & 0 deletions src/codegen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ pub enum HostFunctions {
StringNewFromLinearMemory,
StrKeyToAddr,
GetLedgerTimestamp,
GetLedgerSequence,
GetCurrentContractAddress,
BytesNewFromLinearMemory,
BytesLen,
Expand Down Expand Up @@ -189,6 +190,7 @@ impl HostFunctions {
HostFunctions::VecPushBack => "v.6",
HostFunctions::StringNewFromLinearMemory => "b.i",
HostFunctions::StrKeyToAddr => "a.1",
HostFunctions::GetLedgerSequence => "x.3",
HostFunctions::GetLedgerTimestamp => "x.4",
HostFunctions::GetCurrentContractAddress => "x.7",
HostFunctions::BytesNewFromLinearMemory => "b.3",
Expand Down
2 changes: 2 additions & 0 deletions src/emit/soroban/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ impl HostFunctions {
.fn_type(&[ty.into(), ty.into()], false),
HostFunctions::StrKeyToAddr => bin.context.i64_type().fn_type(&[ty.into()], false),
HostFunctions::GetLedgerTimestamp => bin.context.i64_type().fn_type(&[], false),
HostFunctions::GetLedgerSequence => bin.context.i64_type().fn_type(&[], false),
HostFunctions::GetCurrentContractAddress => bin.context.i64_type().fn_type(&[], false),
HostFunctions::ObjToI128Lo64 => bin.context.i64_type().fn_type(&[ty.into()], false),
HostFunctions::ObjToI128Hi64 => bin.context.i64_type().fn_type(&[ty.into()], false),
Expand Down Expand Up @@ -467,6 +468,7 @@ impl SorobanTarget {
HostFunctions::StringNewFromLinearMemory,
HostFunctions::StrKeyToAddr,
HostFunctions::GetLedgerTimestamp,
HostFunctions::GetLedgerSequence,
HostFunctions::GetCurrentContractAddress,
HostFunctions::BytesNewFromLinearMemory,
HostFunctions::BytesCopyToLinearMemory,
Expand Down
30 changes: 30 additions & 0 deletions src/emit/soroban/target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1063,6 +1063,36 @@ impl<'a> TargetRuntime<'a> for SorobanTarget {

value.into()
}
Expression::Builtin {
loc,
tys,
kind: Builtin::BlockNumber,
args,
} => {
let function_name = HostFunctions::GetLedgerSequence.name();
let function_value =
runtime_helper(bin, function_name, "reading Soroban ledger sequence number/block.number");

let u32_val = bin
.builder
.build_call(function_value, &[], function_name)
.unwrap()
.try_as_basic_value()
.left()
.unwrap()
.into_int_value();

return bin
.builder
.build_right_shift(
u32_val,
bin.context.i64_type().const_int(32, false),
false,
"block",
)
.unwrap()
.into();
}
_ => unsupported_soroban(expr.loc(), "this Soroban builtin"),
}
}
Expand Down
25 changes: 25 additions & 0 deletions tests/soroban_testcases/block_number.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use crate::build_solidity;
use soroban_sdk::testutils::Ledger;
use soroban_sdk::{FromVal, Val};

#[test]
fn get_ledger_sequence() {
let runtime = build_solidity(
r#"
contract LedgerSequence {
function get_ledger_sequence() public view returns (uint64) {
return block.number;
}
}
"#,
|_| {},
);
let addr = runtime.contracts.last().unwrap();
let samples: Vec<u64> = vec![1, 99, 2, 33, 13, 9, 15, 10001, 2 << 16, 2 << 24];
for number in samples {
runtime.env.ledger().set_sequence_number(number as u32);
let block_number_val: Val = runtime.invoke_contract(addr, "get_ledger_sequence", vec![]);
let block_number_u64: u64 = FromVal::from_val(&runtime.env, &block_number_val);
assert_eq!(number, block_number_u64);
}
}
1 change: 1 addition & 0 deletions tests/soroban_testcases/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ mod alloc;
mod array_args;
mod atomic_swap;
mod auth;
mod block_number;
mod constructor;
mod cross_contract_calls;
mod events;
Expand Down