diff --git a/crates/integration/codesize.json b/crates/integration/codesize.json index 868c594..4c7d0ca 100644 --- a/crates/integration/codesize.json +++ b/crates/integration/codesize.json @@ -1,10 +1,10 @@ { - "Baseline": 967, - "Computation": 4022, - "DivisionArithmetics": 31787, - "ERC20": 44233, - "Events": 1743, - "FibonacciIterative": 2927, - "Flipper": 3408, - "SHA1": 26009 + "Baseline": 961, + "Computation": 4024, + "DivisionArithmetics": 31789, + "ERC20": 44214, + "Events": 1737, + "FibonacciIterative": 2929, + "Flipper": 3402, + "SHA1": 26003 } \ No newline at end of file diff --git a/crates/integration/contracts/BlockHash.sol b/crates/integration/contracts/BlockHash.sol new file mode 100644 index 0000000..29a14b7 --- /dev/null +++ b/crates/integration/contracts/BlockHash.sol @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8; + +/* runner.json +{ + "differential": false, + "actions": [ + { + "Instantiate": { + "code": { + "Solidity": { + "contract": "Context" + } + }, + "data": "4545454545454545454545454545454545454545454545454545454545454545" + } + } + ] +} +*/ + +contract BlockHash { + constructor(bytes32 expected) payable { + assert(blockhash(0) == expected); + assert(blockhash(1) == 0); + assert( + blockhash( + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ) == 0 + ); + } +} diff --git a/crates/integration/src/tests.rs b/crates/integration/src/tests.rs index 810df50..c8a9c50 100644 --- a/crates/integration/src/tests.rs +++ b/crates/integration/src/tests.rs @@ -44,6 +44,7 @@ test_spec!(transfer, "Transfer", "Transfer.sol"); test_spec!(return_data_oob, "ReturnDataOob", "ReturnDataOob.sol"); test_spec!(immutables, "Immutables", "Immutables.sol"); test_spec!(transaction, "Transaction", "Transaction.sol"); +test_spec!(block_hash, "BlockHash", "BlockHash.sol"); fn instantiate(path: &str, contract: &str) -> Vec { vec![Instantiate { diff --git a/crates/llvm-context/src/polkavm/evm/context.rs b/crates/llvm-context/src/polkavm/evm/context.rs index f5d6650..825f722 100644 --- a/crates/llvm-context/src/polkavm/evm/context.rs +++ b/crates/llvm-context/src/polkavm/evm/context.rs @@ -74,13 +74,24 @@ where /// Translates the `block_hash` instruction. pub fn block_hash<'ctx, D>( - _context: &mut Context<'ctx, D>, - _index: inkwell::values::IntValue<'ctx>, + context: &mut Context<'ctx, D>, + index: inkwell::values::IntValue<'ctx>, ) -> anyhow::Result> where D: Dependency + Clone, { - todo!() + let output_pointer = context.build_alloca_at_entry(context.word_type(), "blockhash_out_ptr"); + let index_ptr = context.build_alloca_at_entry(context.word_type(), "blockhash_index_ptr"); + context.build_store(index_ptr, index)?; + + context.build_runtime_call( + revive_runtime_api::polkavm_imports::BLOCK_HASH, + &[ + index_ptr.to_int(context).into(), + output_pointer.to_int(context).into(), + ], + ); + context.build_byte_swap(context.build_load(output_pointer, "block_hash")?) } /// Translates the `difficulty` instruction. diff --git a/crates/runtime-api/src/polkavm_imports.c b/crates/runtime-api/src/polkavm_imports.c index a5a28cb..68133aa 100644 --- a/crates/runtime-api/src/polkavm_imports.c +++ b/crates/runtime-api/src/polkavm_imports.c @@ -70,6 +70,8 @@ POLKAVM_IMPORT(void, balance, uint32_t) POLKAVM_IMPORT(void, balance_of, uint32_t, uint32_t) +POLKAVM_IMPORT(void, block_hash, uint32_t, uint32_t) + POLKAVM_IMPORT(void, block_number, uint32_t) POLKAVM_IMPORT(uint32_t, call, uint32_t) diff --git a/crates/runtime-api/src/polkavm_imports.rs b/crates/runtime-api/src/polkavm_imports.rs index f97ffde..2036a00 100644 --- a/crates/runtime-api/src/polkavm_imports.rs +++ b/crates/runtime-api/src/polkavm_imports.rs @@ -20,6 +20,8 @@ pub static BALANCE: &str = "balance"; pub static BALANCE_OF: &str = "balance_of"; +pub static BLOCK_HASH: &str = "block_hash"; + pub static BLOCK_NUMBER: &str = "block_number"; pub static CALL: &str = "call"; @@ -62,12 +64,13 @@ pub static VALUE_TRANSFERRED: &str = "value_transferred"; /// All imported runtime API symbols. /// Useful for configuring common attributes and linkage. -pub static IMPORTS: [&str; 25] = [ +pub static IMPORTS: [&str; 26] = [ SBRK, MEMORY_SIZE, ADDRESS, BALANCE, BALANCE_OF, + BLOCK_HASH, BLOCK_NUMBER, CALL, CALLER,