diff --git a/substrate/frame/revive/fixtures/contracts/block_author.rs b/substrate/frame/revive/fixtures/contracts/block_author.rs new file mode 100644 index 000000000000..59886a19cc61 --- /dev/null +++ b/substrate/frame/revive/fixtures/contracts/block_author.rs @@ -0,0 +1,37 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#![no_std] +#![no_main] + +use common::input; +use uapi::{HostFn, HostFnImpl as api}; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() {} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() { + input!(expected: &[u8; 20],); + + let mut received = [0; 20]; + api::block_author(&mut received); + + assert_eq!(expected, &received); +} diff --git a/substrate/frame/revive/src/tests.rs b/substrate/frame/revive/src/tests.rs index 664578bf7672..2ace8886e3c5 100644 --- a/substrate/frame/revive/src/tests.rs +++ b/substrate/frame/revive/src/tests.rs @@ -55,7 +55,7 @@ use frame_support::{ traits::{ fungible::{BalancedHold, Inspect, Mutate, MutateHold}, tokens::Preservation, - ConstU32, ConstU64, Contains, OnIdle, OnInitialize, StorageVersion, + ConstU32, ConstU64, Contains, FindAuthor, OnIdle, OnInitialize, StorageVersion, }, weights::{constants::WEIGHT_REF_TIME_PER_SECOND, FixedFee, IdentityFee, Weight, WeightMeter}, }; @@ -509,6 +509,15 @@ parameter_types! { pub static UnstableInterface: bool = true; } +impl FindAuthor<::AccountId> for Test { + fn find_author<'a, I>(_digests: I) -> Option<::AccountId> + where + I: 'a + IntoIterator, + { + Some(EVE) + } +} + #[derive_impl(crate::config_preludes::TestDefaultConfig)] impl Config for Test { type Time = Timestamp; @@ -525,6 +534,7 @@ impl Config for Test { type CodeHashLockupDepositPercent = CodeHashLockupDepositPercent; type Debug = TestDebug; type ChainId = ChainId; + type FindAuthor = Test; } impl TryFrom for crate::Call { @@ -4024,6 +4034,21 @@ fn block_hash_works() { }); } +#[test] +fn block_author_works() { + let (code, _) = compile_module("block_author").unwrap(); + + ExtBuilder::default().existential_deposit(1).build().execute_with(|| { + let _ = ::Currency::set_balance(&ALICE, 1_000_000); + + let Contract { addr, .. } = + builder::bare_instantiate(Code::Upload(code)).build_and_unwrap_contract(); + + // The fixture asserts the input to match the find_author API method output. + assert_ok!(builder::call(addr).data(EVE_ADDR.encode()).build()); + }); +} + #[test] fn root_cannot_upload_code() { let (wasm, _) = compile_module("dummy").unwrap(); diff --git a/substrate/frame/revive/uapi/src/host.rs b/substrate/frame/revive/uapi/src/host.rs index eced4843b552..90c98c426196 100644 --- a/substrate/frame/revive/uapi/src/host.rs +++ b/substrate/frame/revive/uapi/src/host.rs @@ -398,6 +398,13 @@ pub trait HostFn: private::Sealed { /// Returns the amount of ref_time left. fn ref_time_left() -> u64; + /// Stores the current block author of into the supplied buffer. + /// + /// # Parameters + /// + /// - `output`: A reference to the output data buffer to write the block author. + fn block_author(output: &mut [u8; 20]); + /// Stores the current block number of the current contract into the supplied buffer. /// /// # Parameters diff --git a/substrate/frame/revive/uapi/src/host/riscv64.rs b/substrate/frame/revive/uapi/src/host/riscv64.rs index 6fdda86892d5..a9f1a0efdf9a 100644 --- a/substrate/frame/revive/uapi/src/host/riscv64.rs +++ b/substrate/frame/revive/uapi/src/host/riscv64.rs @@ -98,6 +98,7 @@ mod sys { pub fn call_data_size() -> u64; pub fn block_number(out_ptr: *mut u8); pub fn block_hash(block_number_ptr: *const u8, out_ptr: *mut u8); + pub fn block_author(out_ptr: *mut u8); pub fn hash_sha2_256(input_ptr: *const u8, input_len: u32, out_ptr: *mut u8); pub fn hash_keccak_256(input_ptr: *const u8, input_len: u32, out_ptr: *mut u8); pub fn hash_blake2_256(input_ptr: *const u8, input_len: u32, out_ptr: *mut u8); @@ -411,6 +412,10 @@ impl HostFn for HostFnImpl { unsafe { sys::block_number(output.as_mut_ptr()) } } + fn block_author(output: &mut [u8; 20]) { + unsafe { sys::block_author(output.as_mut_ptr()) } + } + fn weight_to_fee(ref_time_limit: u64, proof_size_limit: u64, output: &mut [u8; 32]) { unsafe { sys::weight_to_fee(ref_time_limit, proof_size_limit, output.as_mut_ptr()) }; }