Skip to content

Commit 2d53238

Browse files
xermicusatheigithub-actions[bot]
authored
[pallet-revive] implement the block author API (#7198)
This PR implements the block author API method. Runtimes ought to implement it such that it corresponds to the `coinbase` EVM opcode. --------- Signed-off-by: xermicus <cyrill@parity.io> Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com> Co-authored-by: command-bot <> Co-authored-by: Alexander Theißen <alex.theissen@me.com> Co-authored-by: cmd[bot] <41898282+github-actions[bot]@users.noreply.github.com>
1 parent f373af0 commit 2d53238

16 files changed

Lines changed: 913 additions & 715 deletions

File tree

Cargo.lock

Lines changed: 101 additions & 127 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1081,6 +1081,7 @@ impl pallet_revive::Config for Runtime {
10811081
type ChainId = ConstU64<420_420_421>;
10821082
type NativeToEthRatio = ConstU32<1_000_000>; // 10^(18 - 12) Eth is 10^18, Native is 10^12.
10831083
type EthGasEncoder = ();
1084+
type FindAuthor = <Runtime as pallet_authorship::Config>::FindAuthor;
10841085
}
10851086

10861087
impl TryFrom<RuntimeCall> for pallet_revive::Call<Runtime> {

prdoc/pr_7198.prdoc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
title: '[pallet-revive] implement the block author API '
2+
doc:
3+
- audience: Runtime Dev
4+
description: This PR implements the block author API method. Runtimes ought to implement
5+
it such that it corresponds to the `coinbase` EVM opcode.
6+
crates:
7+
- name: pallet-revive
8+
bump: major
9+
- name: pallet-revive-fixtures
10+
bump: minor
11+
- name: pallet-revive-uapi
12+
bump: minor

substrate/bin/node/runtime/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1495,6 +1495,7 @@ impl pallet_revive::Config for Runtime {
14951495
type ChainId = ConstU64<420_420_420>;
14961496
type NativeToEthRatio = ConstU32<1_000_000>; // 10^(18 - 12) Eth is 10^18, Native is 10^12.
14971497
type EthGasEncoder = ();
1498+
type FindAuthor = <Runtime as pallet_authorship::Config>::FindAuthor;
14981499
}
14991500

15001501
impl pallet_sudo::Config for Runtime {

substrate/frame/revive/Cargo.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ pallet-revive-uapi = { workspace = true, features = ["scale"] }
4444
pallet-transaction-payment = { workspace = true }
4545
sp-api = { workspace = true }
4646
sp-arithmetic = { workspace = true }
47+
sp-consensus-aura = { workspace = true, optional = true }
48+
sp-consensus-babe = { workspace = true, optional = true }
49+
sp-consensus-slots = { workspace = true, optional = true }
4750
sp-core = { workspace = true }
4851
sp-io = { workspace = true }
4952
sp-runtime = { workspace = true }
@@ -96,6 +99,9 @@ std = [
9699
"serde_json/std",
97100
"sp-api/std",
98101
"sp-arithmetic/std",
102+
"sp-consensus-aura/std",
103+
"sp-consensus-babe/std",
104+
"sp-consensus-slots/std",
99105
"sp-core/std",
100106
"sp-io/std",
101107
"sp-keystore/std",
@@ -114,6 +120,9 @@ runtime-benchmarks = [
114120
"pallet-timestamp/runtime-benchmarks",
115121
"pallet-transaction-payment/runtime-benchmarks",
116122
"pallet-utility/runtime-benchmarks",
123+
"sp-consensus-aura",
124+
"sp-consensus-babe",
125+
"sp-consensus-slots",
117126
"sp-runtime/runtime-benchmarks",
118127
"xcm-builder/runtime-benchmarks",
119128
"xcm/runtime-benchmarks",
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// This file is part of Substrate.
2+
3+
// Copyright (C) Parity Technologies (UK) Ltd.
4+
// SPDX-License-Identifier: Apache-2.0
5+
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
18+
#![no_std]
19+
#![no_main]
20+
21+
use common::input;
22+
use uapi::{HostFn, HostFnImpl as api};
23+
24+
#[no_mangle]
25+
#[polkavm_derive::polkavm_export]
26+
pub extern "C" fn deploy() {}
27+
28+
#[no_mangle]
29+
#[polkavm_derive::polkavm_export]
30+
pub extern "C" fn call() {
31+
input!(expected: &[u8; 20],);
32+
33+
let mut received = [0; 20];
34+
api::block_author(&mut received);
35+
36+
assert_eq!(expected, &received);
37+
}

substrate/frame/revive/fixtures/contracts/create_transient_storage_and_call.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
use common::input;
2323
use uapi::{HostFn, HostFnImpl as api, StorageFlags};
2424

25-
static BUFFER: [u8; 448] = [0u8; 448];
25+
static BUFFER: [u8; 416] = [0u8; 416];
2626

2727
#[no_mangle]
2828
#[polkavm_derive::polkavm_export]

substrate/frame/revive/src/benchmarking/mod.rs

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,16 @@ use frame_support::{
4040
};
4141
use frame_system::RawOrigin;
4242
use pallet_revive_uapi::{pack_hi_lo, CallFlags, ReturnErrorCode, StorageFlags};
43-
use sp_runtime::traits::{Bounded, Hash};
43+
use sp_consensus_aura::AURA_ENGINE_ID;
44+
use sp_consensus_babe::{
45+
digests::{PreDigest, PrimaryPreDigest},
46+
BABE_ENGINE_ID,
47+
};
48+
use sp_consensus_slots::Slot;
49+
use sp_runtime::{
50+
generic::{Digest, DigestItem},
51+
traits::{Bounded, Hash},
52+
};
4453

4554
/// How many runs we do per API benchmark.
4655
///
@@ -886,6 +895,59 @@ mod benchmarks {
886895
assert_eq!(U256::from_little_endian(&memory[..]), runtime.ext().block_number());
887896
}
888897

898+
#[benchmark(pov_mode = Measured)]
899+
fn seal_block_author() {
900+
build_runtime!(runtime, memory: [[123u8; 20], ]);
901+
902+
let mut digest = Digest::default();
903+
904+
// The pre-runtime digest log is unbounded; usually around 3 items but it can vary.
905+
// To get safe benchmark results despite that, populate it with a bunch of random logs to
906+
// ensure iteration over many items (we just overestimate the cost of the API).
907+
for i in 0..16 {
908+
digest.push(DigestItem::PreRuntime([i, i, i, i], vec![i; 128]));
909+
digest.push(DigestItem::Consensus([i, i, i, i], vec![i; 128]));
910+
digest.push(DigestItem::Seal([i, i, i, i], vec![i; 128]));
911+
digest.push(DigestItem::Other(vec![i; 128]));
912+
}
913+
914+
// The content of the pre-runtime digest log depends on the configured consensus.
915+
// However, mismatching logs are simply ignored. Thus we construct fixtures which will
916+
// let the API to return a value in both BABE and AURA consensus.
917+
918+
// Construct a `Digest` log fixture returning some value in BABE
919+
let primary_pre_digest = vec![0; <PrimaryPreDigest as MaxEncodedLen>::max_encoded_len()];
920+
let pre_digest =
921+
PreDigest::Primary(PrimaryPreDigest::decode(&mut &primary_pre_digest[..]).unwrap());
922+
digest.push(DigestItem::PreRuntime(BABE_ENGINE_ID, pre_digest.encode()));
923+
digest.push(DigestItem::Seal(BABE_ENGINE_ID, pre_digest.encode()));
924+
925+
// Construct a `Digest` log fixture returning some value in AURA
926+
let slot = Slot::default();
927+
digest.push(DigestItem::PreRuntime(AURA_ENGINE_ID, slot.encode()));
928+
digest.push(DigestItem::Seal(AURA_ENGINE_ID, slot.encode()));
929+
930+
frame_system::Pallet::<T>::initialize(
931+
&BlockNumberFor::<T>::from(1u32),
932+
&Default::default(),
933+
&digest,
934+
);
935+
936+
let result;
937+
#[block]
938+
{
939+
result = runtime.bench_block_author(memory.as_mut_slice(), 0);
940+
}
941+
assert_ok!(result);
942+
943+
let block_author = runtime
944+
.ext()
945+
.block_author()
946+
.map(|account| T::AddressMapper::to_address(&account))
947+
.unwrap_or(H160::zero());
948+
assert_eq!(&memory[..], block_author.as_bytes());
949+
}
950+
889951
#[benchmark(pov_mode = Measured)]
890952
fn seal_block_hash() {
891953
let mut memory = vec![0u8; 64];

substrate/frame/revive/src/exec.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ use frame_support::{
3737
traits::{
3838
fungible::{Inspect, Mutate},
3939
tokens::{Fortitude, Preservation},
40-
Contains, OriginTrait, Time,
40+
Contains, FindAuthor, OriginTrait, Time,
4141
},
4242
weights::Weight,
4343
Blake2_128Concat, BoundedVec, StorageHasher,
@@ -366,6 +366,9 @@ pub trait Ext: sealing::Sealed {
366366
/// `block_number` isn't within the range of the previous 256 blocks.
367367
fn block_hash(&self, block_number: U256) -> Option<H256>;
368368

369+
/// Returns the author of the current block.
370+
fn block_author(&self) -> Option<AccountIdOf<Self::T>>;
371+
369372
/// Returns the maximum allowed size of a storage item.
370373
fn max_value_size(&self) -> u32;
371374

@@ -1718,6 +1721,13 @@ where
17181721
self.block_hash(block_number)
17191722
}
17201723

1724+
fn block_author(&self) -> Option<AccountIdOf<Self::T>> {
1725+
let digest = <frame_system::Pallet<T>>::digest();
1726+
let pre_runtime_digests = digest.logs.iter().filter_map(|d| d.as_pre_runtime());
1727+
1728+
T::FindAuthor::find_author(pre_runtime_digests)
1729+
}
1730+
17211731
fn max_value_size(&self) -> u32 {
17221732
limits::PAYLOAD_BYTES
17231733
}

substrate/frame/revive/src/lib.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ const LOG_TARGET: &str = "runtime::revive";
114114
#[frame_support::pallet]
115115
pub mod pallet {
116116
use super::*;
117-
use frame_support::pallet_prelude::*;
117+
use frame_support::{pallet_prelude::*, traits::FindAuthor};
118118
use frame_system::pallet_prelude::*;
119119
use sp_core::U256;
120120
use sp_runtime::Perbill;
@@ -189,6 +189,9 @@ pub mod pallet {
189189
#[pallet::no_default_bounds]
190190
type ChainExtension: chain_extension::ChainExtension<Self> + Default;
191191

192+
/// Find the author of the current block.
193+
type FindAuthor: FindAuthor<Self::AccountId>;
194+
192195
/// The amount of balance a caller has to pay for each byte of storage.
193196
///
194197
/// # Note
@@ -362,6 +365,7 @@ pub mod pallet {
362365
type ChainId = ConstU64<0>;
363366
type NativeToEthRatio = ConstU32<1>;
364367
type EthGasEncoder = ();
368+
type FindAuthor = ();
365369
}
366370
}
367371

0 commit comments

Comments
 (0)