Skip to content
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
2c8637a
the block_author API
xermicus Jan 14, 2025
31217da
the benchmark
xermicus Jan 15, 2025
19d5074
the runtime API method
xermicus Jan 16, 2025
acea813
Merge branch 'master' into cl/coinbase
xermicus Jan 16, 2025
9f2e141
Update from xermicus running command 'prdoc --audience runtime_dev --…
Jan 16, 2025
a8e1021
the westend asset hub runtime configuration
xermicus Jan 16, 2025
39a1d7c
Update from xermicus running command 'bench --runtime dev --pallet pa…
Jan 16, 2025
c3fd4d5
the kitchensink runtime configuration
xermicus Jan 16, 2025
e886ae3
Merge branch 'master' into cl/coinbase
xermicus Jan 16, 2025
7542ba6
Update from xermicus running command 'bench --runtime dev --pallet pa…
Jan 16, 2025
8a8b0e9
populate digest
xermicus Jan 22, 2025
0082fd3
Update prdoc/pr_7198.prdoc
xermicus Jan 22, 2025
81a3c65
Update from xermicus running command 'bench --runtime dev --pallet pa…
Jan 22, 2025
470530f
fix benchmark
xermicus Jan 27, 2025
cd90457
Merge branch 'master' into cl/coinbase
xermicus Jan 27, 2025
244a2fd
the runtime benchmark dependencies
xermicus Jan 27, 2025
11f66ea
Update from xermicus running command 'fmt'
github-actions[bot] Jan 27, 2025
f745027
Update from xermicus running command 'bench --runtime dev --pallet pa…
github-actions[bot] Jan 27, 2025
21b4c70
cleanup
xermicus Jan 27, 2025
1592bc7
the std feature propagation
xermicus Jan 27, 2025
d131571
the Cargo.toml dependency alphanumeric sort order
xermicus Jan 27, 2025
9bd6a77
typo
xermicus Jan 27, 2025
6ee6664
Merge branch 'master' into cl/coinbase
xermicus Jan 27, 2025
76d5a50
reset weights.rs
xermicus Jan 27, 2025
b62c08d
Merge branch 'master' into cl/coinbase
xermicus Jan 27, 2025
1d5f4f4
the TestDefaultConfig configuration
xermicus Jan 27, 2025
f3f35f0
Merge branch 'master' into cl/coinbase
xermicus Jan 27, 2025
d4b562e
testdefaultconfig
xermicus Jan 27, 2025
f0f18c9
Merge branch 'master' into cl/coinbase
xermicus Jan 28, 2025
c3fb6c4
Merge branch 'master' into cl/coinbase
xermicus Jan 28, 2025
a17e58e
do not expect a block author in the benchmark
xermicus Jan 29, 2025
ea58762
Merge branch 'master' into cl/coinbase
xermicus Jan 29, 2025
bd6a010
Update from xermicus running command 'bench-omni --runtime dev --pall…
github-actions[bot] Jan 29, 2025
4ee43c5
run the benchmark after genesis block
xermicus Jan 29, 2025
fa75fa2
fix the tests after updated weights
xermicus Jan 29, 2025
bf6b04b
Merge branch 'master' into cl/coinbase
xermicus Jan 29, 2025
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
Original file line number Diff line number Diff line change
Expand Up @@ -1082,6 +1082,7 @@ impl pallet_revive::Config for Runtime {
type ChainId = ConstU64<420_420_421>;
type NativeToEthRatio = ConstU32<1_000_000>; // 10^(18 - 12) Eth is 10^18, Native is 10^12.
type EthGasEncoder = ();
type FindAuthor = <Runtime as pallet_authorship::Config>::FindAuthor;
}

impl TryFrom<RuntimeCall> for pallet_revive::Call<Runtime> {
Expand Down
12 changes: 12 additions & 0 deletions prdoc/pr_7198.prdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
title: '[pallet-revive] implement the block author API '
doc:
- audience: Runtime Dev
description: This PR implements the block author API method. Runtimes ought to implement
it such that it corresponds to the `coinbase` EVM opcode.
crates:
- name: pallet-revive
bump: major
- name: pallet-revive-fixtures
bump: minor
- name: pallet-revive-uapi
bump: minor
1 change: 1 addition & 0 deletions substrate/bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1476,6 +1476,7 @@ impl pallet_revive::Config for Runtime {
type ChainId = ConstU64<420_420_420>;
type NativeToEthRatio = ConstU32<1_000_000>; // 10^(18 - 12) Eth is 10^18, Native is 10^12.
type EthGasEncoder = ();
type FindAuthor = <Runtime as pallet_authorship::Config>::FindAuthor;
}

impl pallet_sudo::Config for Runtime {
Expand Down
37 changes: 37 additions & 0 deletions substrate/frame/revive/fixtures/contracts/block_author.rs
Original file line number Diff line number Diff line change
@@ -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);
}
24 changes: 24 additions & 0 deletions substrate/frame/revive/src/benchmarking/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ use frame_support::{
use frame_system::RawOrigin;
use pallet_revive_uapi::{CallFlags, ReturnErrorCode, StorageFlags};
use sp_runtime::traits::{Bounded, Hash};
use sp_runtime::generic::{Digest, DigestItem};

/// How many runs we do per API benchmark.
///
Expand Down Expand Up @@ -886,6 +887,29 @@ mod benchmarks {
assert_eq!(U256::from_little_endian(&memory[..]), runtime.ext().block_number());
}

#[benchmark(pov_mode = Measured)]
fn seal_block_author() {
build_runtime!(runtime, memory: [[123u8; 20], ]);

let mut digest = Digest::default();
digest.push(DigestItem::PreRuntime([1, 2, 3, 4], 123.encode()));
digest.push(DigestItem::Seal([1, 2, 4, 4], 123.encode()));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a realistic amount of messages to be expected in this Vec? Is this the worst case?

Copy link
Copy Markdown
Member Author

@xermicus xermicus Jan 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see #[pallet::unbounded] over Digest and log is just alloc::vec::Vec. I don't see anything indicating this to be bounded.

frame_system::Pallet::<T>::initialize(&Default::default(), &Default::default(), &digest);

let result;
#[block]
{
result = runtime.bench_block_author(memory.as_mut_slice(), 0);
}
assert_ok!(result);
let block_author = runtime
.ext()
.block_author()
.map(|account| T::AddressMapper::to_address(&account))
.unwrap_or(H160::zero());
assert_eq!(&memory[..], block_author.as_bytes());
}

#[benchmark(pov_mode = Measured)]
fn seal_block_hash() {
let mut memory = vec![0u8; 64];
Expand Down
12 changes: 11 additions & 1 deletion substrate/frame/revive/src/exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ use frame_support::{
traits::{
fungible::{Inspect, Mutate},
tokens::{Fortitude, Preservation},
Contains, OriginTrait, Time,
Contains, FindAuthor, OriginTrait, Time,
},
weights::Weight,
Blake2_128Concat, BoundedVec, StorageHasher,
Expand Down Expand Up @@ -366,6 +366,9 @@ pub trait Ext: sealing::Sealed {
/// `block_number` isn't within the range of the previous 256 blocks.
fn block_hash(&self, block_number: U256) -> Option<H256>;

/// Returns the author of the current block.
fn block_author(&self) -> Option<AccountIdOf<Self::T>>;

/// Returns the maximum allowed size of a storage item.
fn max_value_size(&self) -> u32;

Expand Down Expand Up @@ -1676,6 +1679,13 @@ where
self.block_hash(block_number)
}

fn block_author(&self) -> Option<AccountIdOf<Self::T>> {
let digest = <frame_system::Pallet<T>>::digest();
let pre_runtime_digests = digest.logs.iter().filter_map(|d| d.as_pre_runtime());

T::FindAuthor::find_author(pre_runtime_digests)
}

fn max_value_size(&self) -> u32 {
limits::PAYLOAD_BYTES
}
Expand Down
6 changes: 5 additions & 1 deletion substrate/frame/revive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ const LOG_TARGET: &str = "runtime::revive";
pub mod pallet {
use super::*;
use crate::debug::Debugger;
use frame_support::pallet_prelude::*;
use frame_support::{pallet_prelude::*, traits::FindAuthor};
use frame_system::pallet_prelude::*;
use sp_core::U256;
use sp_runtime::Perbill;
Expand Down Expand Up @@ -194,6 +194,9 @@ pub mod pallet {
#[pallet::no_default_bounds]
type ChainExtension: chain_extension::ChainExtension<Self> + Default;

/// Find the author of the current block.
type FindAuthor: FindAuthor<Self::AccountId>;

/// The amount of balance a caller has to pay for each byte of storage.
///
/// # Note
Expand Down Expand Up @@ -374,6 +377,7 @@ pub mod pallet {
type ChainId = ConstU64<0>;
type NativeToEthRatio = ConstU32<1>;
type EthGasEncoder = ();
type FindAuthor = ();
}
}

Expand Down
27 changes: 26 additions & 1 deletion substrate/frame/revive/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
};
Expand Down Expand Up @@ -509,6 +509,15 @@ parameter_types! {
pub static UnstableInterface: bool = true;
}

impl FindAuthor<<Test as frame_system::Config>::AccountId> for Test {
fn find_author<'a, I>(_digests: I) -> Option<<Test as frame_system::Config>::AccountId>
where
I: 'a + IntoIterator<Item = (frame_support::ConsensusEngineId, &'a [u8])>,
{
Some(EVE)
}
}

#[derive_impl(crate::config_preludes::TestDefaultConfig)]
impl Config for Test {
type Time = Timestamp;
Expand All @@ -525,6 +534,7 @@ impl Config for Test {
type CodeHashLockupDepositPercent = CodeHashLockupDepositPercent;
type Debug = TestDebug;
type ChainId = ChainId;
type FindAuthor = Test;
}

impl TryFrom<RuntimeCall> for crate::Call<Test> {
Expand Down Expand Up @@ -3599,6 +3609,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 _ = <Test as Config>::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();
Expand Down
22 changes: 22 additions & 0 deletions substrate/frame/revive/src/wasm/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,8 @@ pub enum RuntimeCosts {
BlockNumber,
/// Weight of calling `seal_block_hash`.
BlockHash,
/// Weight of calling `seal_block_author`.
BlockAuthor,
/// Weight of calling `seal_gas_price`.
GasPrice,
/// Weight of calling `seal_base_fee`.
Expand Down Expand Up @@ -483,6 +485,7 @@ impl<T: Config> Token<T> for RuntimeCosts {
MinimumBalance => T::WeightInfo::seal_minimum_balance(),
BlockNumber => T::WeightInfo::seal_block_number(),
BlockHash => T::WeightInfo::seal_block_hash(),
BlockAuthor => T::WeightInfo::seal_block_author(),
GasPrice => T::WeightInfo::seal_gas_price(),
BaseFee => T::WeightInfo::seal_base_fee(),
Now => T::WeightInfo::seal_now(),
Expand Down Expand Up @@ -1676,6 +1679,25 @@ pub mod env {
)?)
}

/// Stores the current block author into the supplied buffer.
/// See [`pallet_revive_uapi::HostFn::block_author`].
#[stable]
fn block_author(&mut self, memory: &mut M, out_ptr: u32) -> Result<(), TrapReason> {
self.charge_gas(RuntimeCosts::BlockAuthor)?;
let block_author = self
.ext
.block_author()
.map(|account| <E::T as Config>::AddressMapper::to_address(&account))
.unwrap_or(H160::zero());
Ok(self.write_fixed_sandbox_output(
memory,
out_ptr,
&block_author.as_bytes(),
false,
already_charged,
)?)
}

/// Computes the KECCAK 256-bit hash on the given input buffer.
/// See [`pallet_revive_uapi::HostFn::hash_keccak_256`].
#[stable]
Expand Down
Loading