diff --git a/crates/integration/contracts/Transaction.sol b/crates/integration/contracts/Transaction.sol new file mode 100644 index 0000000..2455f70 --- /dev/null +++ b/crates/integration/contracts/Transaction.sol @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/* runner.json +{ + "differential": true, + "actions": [ + { + "Upload": { + "code": { + "Solidity": { + "contract": "TransactionOrigin" + } + } + } + }, + { + "Instantiate": { + "code": { + "Solidity": { + "contract": "TransactionTester" + } + } + } + }, + { + "Call": { + "dest": { + "Instantiated": 0 + }, + "data": "f8a8fd6d" + } + } + ] +} +*/ + +contract TransactionTester { + constructor() payable { + assert(tx.origin == new TransactionOrigin().test()); + } + + function test() public payable returns (address ret) { + ret = tx.origin; + } +} + +contract TransactionOrigin { + function test() public payable returns (address ret) { + assert(msg.sender != tx.origin); + + ret = tx.origin; + } +} diff --git a/crates/integration/src/tests.rs b/crates/integration/src/tests.rs index 8cd26f5..9b497f6 100644 --- a/crates/integration/src/tests.rs +++ b/crates/integration/src/tests.rs @@ -43,6 +43,7 @@ test_spec!(call, "Caller", "Call.sol"); 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"); 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 cf4adeb..f5d6650 100644 --- a/crates/llvm-context/src/polkavm/evm/context.rs +++ b/crates/llvm-context/src/polkavm/evm/context.rs @@ -27,12 +27,19 @@ where /// Translates the `tx.origin` instruction. pub fn origin<'ctx, D>( - _context: &mut Context<'ctx, D>, + context: &mut Context<'ctx, D>, ) -> anyhow::Result> where D: Dependency + Clone, { - todo!() + let address_type = context.integer_type(revive_common::BIT_LENGTH_ETH_ADDRESS); + let address_pointer = context.build_alloca_at_entry(address_type, "origin_address"); + context.build_store(address_pointer, address_type.const_zero())?; + context.build_runtime_call( + revive_runtime_api::polkavm_imports::ORIGIN, + &[address_pointer.to_int(context).into()], + ); + context.build_load_address(address_pointer) } /// Translates the `chain_id` instruction. diff --git a/crates/runtime-api/src/polkavm_imports.c b/crates/runtime-api/src/polkavm_imports.c index 6ccc76a..af399b5 100644 --- a/crates/runtime-api/src/polkavm_imports.c +++ b/crates/runtime-api/src/polkavm_imports.c @@ -96,6 +96,8 @@ POLKAVM_IMPORT(uint32_t, instantiate, uint32_t) POLKAVM_IMPORT(void, now, uint32_t) +POLKAVM_IMPORT(void, origin, uint32_t) + POLKAVM_IMPORT(void, seal_return, uint32_t, uint32_t, uint32_t) POLKAVM_IMPORT(uint32_t, set_storage, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t) diff --git a/crates/runtime-api/src/polkavm_imports.rs b/crates/runtime-api/src/polkavm_imports.rs index a19cb10..f97ffde 100644 --- a/crates/runtime-api/src/polkavm_imports.rs +++ b/crates/runtime-api/src/polkavm_imports.rs @@ -46,6 +46,8 @@ pub static INSTANTIATE: &str = "instantiate"; pub static NOW: &str = "now"; +pub static ORIGIN: &str = "origin"; + pub static RETURN: &str = "seal_return"; pub static SET_STORAGE: &str = "set_storage"; @@ -60,7 +62,7 @@ pub static VALUE_TRANSFERRED: &str = "value_transferred"; /// All imported runtime API symbols. /// Useful for configuring common attributes and linkage. -pub static IMPORTS: [&str; 24] = [ +pub static IMPORTS: [&str; 25] = [ SBRK, MEMORY_SIZE, ADDRESS, @@ -79,6 +81,7 @@ pub static IMPORTS: [&str; 24] = [ INPUT, INSTANTIATE, NOW, + ORIGIN, RETURN, RETURNDATACOPY, RETURNDATASIZE,