Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
15 changes: 14 additions & 1 deletion frame/ethereum/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@
//! Test utilities

use ethereum::{TransactionAction, TransactionSignature};
use frame_system::pallet_prelude::BlockNumberFor;
use rlp::RlpStream;
// Substrate
use frame_support::{derive_impl, parameter_types, traits::FindAuthor, ConsensusEngineId};
use sp_core::{hashing::keccak_256, H160, H256, U256};
use sp_core::{hashing::keccak_256, Hasher, H160, H256, U256};
use sp_runtime::{
traits::{Dispatchable, IdentityLookup},
AccountId32, BuildStorage,
Expand Down Expand Up @@ -91,6 +92,17 @@ parameter_types! {
pub const GasLimitStorageGrowthRatio: u64 = BLOCK_GAS_LIMIT.saturating_div(MAX_STORAGE_GROWTH);
}

pub struct RandomnessProvider;
impl frame_support::traits::Randomness<<Test as frame_system::Config>::Hash, BlockNumberFor<Test>>
for RandomnessProvider
{
fn random(subject: &[u8]) -> (<Test as frame_system::Config>::Hash, BlockNumberFor<Test>) {
let output = <Test as frame_system::Config>::Hashing::hash(subject);
let block_number = frame_system::Pallet::<Test>::block_number();
(output, block_number)
}
}

#[derive_impl(pallet_evm::config_preludes::TestDefaultConfig)]
impl pallet_evm::Config for Test {
type AccountProvider = pallet_evm::FrameSystemAccountProvider<Self>;
Expand All @@ -102,6 +114,7 @@ impl pallet_evm::Config for Test {
type FindAuthor = FindAuthorTruncated;
type GasLimitStorageGrowthRatio = GasLimitStorageGrowthRatio;
type Timestamp = Timestamp;
type RandomnessProvider = RandomnessProvider;
}

#[derive_impl(crate::config_preludes::TestDefaultConfig)]
Expand Down
16 changes: 15 additions & 1 deletion frame/evm/precompile/dispatch/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ use frame_support::{
weights::Weight,
ConsensusEngineId,
};
use sp_core::{H160, H256, U256};
use frame_system::pallet_prelude::BlockNumberFor;
use sp_core::{Hasher, H160, H256, U256};
use sp_runtime::traits::{BlakeTwo256, IdentityLookup};

use fp_evm::{ExitError, ExitReason, Transfer};
Expand Down Expand Up @@ -135,6 +136,18 @@ parameter_types! {
pub WeightPerGas: Weight = Weight::from_parts(20_000, 0);
pub SuicideQuickClearLimit: u32 = 0;
}

pub struct RandomnessProvider;
impl frame_support::traits::Randomness<<Test as frame_system::Config>::Hash, BlockNumberFor<Test>>
for RandomnessProvider
{
fn random(subject: &[u8]) -> (<Test as frame_system::Config>::Hash, BlockNumberFor<Test>) {
let output = <Test as frame_system::Config>::Hashing::hash(subject);
let block_number = frame_system::Pallet::<Test>::block_number();
(output, block_number)
}
}

impl pallet_evm::Config for Test {
type AccountProvider = pallet_evm::FrameSystemAccountProvider<Self>;
type FeeCalculator = FixedGasPrice;
Expand Down Expand Up @@ -162,6 +175,7 @@ impl pallet_evm::Config for Test {
type GasLimitStorageGrowthRatio = ();
type Timestamp = Timestamp;
type WeightInfo = ();
type RandomnessProvider = RandomnessProvider;
}

pub(crate) struct MockHandle {
Expand Down
23 changes: 22 additions & 1 deletion frame/evm/precompile/storage-cleaner/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@

use crate::{StorageCleanerPrecompile, StorageCleanerPrecompileCall};
use frame_support::{parameter_types, weights::Weight};
use frame_system::pallet_prelude::BlockNumberFor;
use pallet_evm::{EnsureAddressNever, EnsureAddressRoot, IdentityAddressMapping};
use precompile_utils::{precompile_set::*, testing::*};
use sp_core::{ConstU32, H256, U256};
use sp_core::{ConstU32, Hasher, H256, U256};
use sp_runtime::{
traits::{BlakeTwo256, IdentityLookup},
BuildStorage,
Expand Down Expand Up @@ -125,6 +126,25 @@ parameter_types! {
pub SuicideQuickClearLimit: u32 = 0;
}

pub struct RandomnessProvider;
impl
frame_support::traits::Randomness<
<Runtime as frame_system::Config>::Hash,
BlockNumberFor<Runtime>,
> for RandomnessProvider
{
fn random(
subject: &[u8],
) -> (
<Runtime as frame_system::Config>::Hash,
BlockNumberFor<Runtime>,
) {
let output = <Runtime as frame_system::Config>::Hashing::hash(subject);
let block_number = frame_system::Pallet::<Runtime>::block_number();
(output, block_number)
}
}

impl pallet_evm::Config for Runtime {
type AccountProvider = pallet_evm::FrameSystemAccountProvider<Self>;
type FeeCalculator = ();
Expand All @@ -149,6 +169,7 @@ impl pallet_evm::Config for Runtime {
type Timestamp = Timestamp;
type WeightInfo = ();
type SuicideQuickClearLimit = SuicideQuickClearLimit;
type RandomnessProvider = RandomnessProvider;
}

/// Build test externalities, prepopulated with data for testing the precompile.
Expand Down
7 changes: 6 additions & 1 deletion frame/evm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,12 @@ pub mod pallet {
/// Weight information for extrinsics in this pallet.
type WeightInfo: WeightInfo;

#[pallet::no_default]
type RandomnessProvider: frame_support::traits::Randomness<
sp_core::H256,
Copy link

Choose a reason for hiding this comment

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

The runtime implementing this pallet may not what to enabled randomness. (For example, the template runtime which currently has a really dangerous example)

Suggested change
sp_core::H256,
Option<sp_core::H256>,

We can also put this type behind a feature, or just allow the random result to be None.

Copy link
Author

@snowmead snowmead Apr 17, 2025

Choose a reason for hiding this comment

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

I want to avoid changing this type to Option because I wouldn't be able to pass the randomness pallet directly as an impl since it implements <Hash, ...>. I would have to wrap it.

BlockNumberFor<Self>,
>;

/// EVM config used in the module.
fn config() -> &'static EvmConfig {
&CANCUN_CONFIG
Expand Down Expand Up @@ -701,7 +707,6 @@ pub mod pallet {
.saturating_add(T::DbWeight::get().reads(1))
.saturating_add(account_basic_weight)
.saturating_add(min_gas_weight);

}

total_weight
Expand Down
15 changes: 14 additions & 1 deletion frame/evm/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
//! Test mock for unit tests and benchmarking

use frame_support::{derive_impl, parameter_types, weights::Weight};
use sp_core::{H160, U256};
use frame_system::pallet_prelude::BlockNumberFor;
use sp_core::{Hasher, H160, U256};

use crate::{
FeeCalculator, IsPrecompileResult, Precompile, PrecompileHandle, PrecompileResult,
Expand Down Expand Up @@ -75,6 +76,18 @@ impl crate::Config for Test {
type Runner = crate::runner::stack::Runner<Self>;
type GasLimitStorageGrowthRatio = GasLimitStorageGrowthRatio;
type Timestamp = Timestamp;
type RandomnessProvider = RandomnessProvider;
}

pub struct RandomnessProvider;
impl frame_support::traits::Randomness<<Test as frame_system::Config>::Hash, BlockNumberFor<Test>>
for RandomnessProvider
{
fn random(subject: &[u8]) -> (<Test as frame_system::Config>::Hash, BlockNumberFor<Test>) {
let output = <Test as frame_system::Config>::Hashing::hash(subject);
let block_number = frame_system::Pallet::<Test>::block_number();
(output, block_number)
}
}

pub struct FixedGasPrice;
Expand Down
8 changes: 7 additions & 1 deletion frame/evm/src/runner/stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -963,7 +963,13 @@ where
}

fn block_randomness(&self) -> Option<H256> {
None
use frame_support::traits::Randomness;
use scale_codec::Encode;

let current_block = frame_system::Pallet::<T>::block_number();
let output = T::RandomnessProvider::random(&current_block.encode()).0;

Some(output)
}

fn block_gas_limit(&self) -> U256 {
Expand Down
22 changes: 21 additions & 1 deletion precompiles/tests-external/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use std::{cell::RefCell, rc::Rc};
use frame_support::{
construct_runtime, derive_impl, parameter_types, traits::Everything, weights::Weight,
};
use sp_core::{H160, H256, U256};
use sp_core::{Hasher, H160, H256, U256};
use sp_runtime::{
traits::{BlakeTwo256, IdentityLookup},
BuildStorage, Perbill,
Expand Down Expand Up @@ -253,6 +253,26 @@ impl pallet_evm::Config for Runtime {
type GasLimitStorageGrowthRatio = ();
type Timestamp = Timestamp;
type WeightInfo = pallet_evm::weights::SubstrateWeight<Runtime>;
type RandomnessProvider = RandomnessProvider;
}

pub struct RandomnessProvider;
impl
frame_support::traits::Randomness<
<Runtime as frame_system::Config>::Hash,
frame_system::pallet_prelude::BlockNumberFor<Runtime>,
> for RandomnessProvider
{
fn random(
subject: &[u8],
) -> (
<Runtime as frame_system::Config>::Hash,
frame_system::pallet_prelude::BlockNumberFor<Runtime>,
) {
let output = <Runtime as frame_system::Config>::Hashing::hash(subject);
let block_number = frame_system::Pallet::<Runtime>::block_number();
(output, block_number)
}
}

parameter_types! {
Expand Down
24 changes: 23 additions & 1 deletion template/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use sp_consensus_aura::sr25519::AuthorityId as AuraId;
use sp_consensus_grandpa::{AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList};
use sp_core::{
crypto::{ByteArray, KeyTypeId},
ConstU128, OpaqueMetadata, H160, H256, U256,
ConstU128, Hasher, OpaqueMetadata, H160, H256, U256,
};
use sp_runtime::{
create_runtime_str, generic, impl_opaque_keys,
Expand Down Expand Up @@ -50,6 +50,7 @@ use sp_genesis_builder::PresetId;
use fp_account::EthereumSignature;
use fp_evm::weight_per_gas;
use fp_rpc::TransactionStatus;
use frame_system::pallet_prelude::BlockNumberFor;
use pallet_ethereum::{Call::transact, PostLogContent, Transaction as EthereumTransaction};
use pallet_evm::{
Account as EVMAccount, EnsureAccountId20, FeeCalculator, IdentityAddressMapping, Runner,
Expand Down Expand Up @@ -336,6 +337,26 @@ impl<F: FindAuthor<u32>> FindAuthor<H160> for FindAuthorTruncated<F> {
}
}

/// WARNING! THIS IS JUST AN EXAMPLE AND SHOULD NOT BE USED AS A MEANS TO RETRIEVE SECURE RANDOMNESS
pub struct RandomnessProvider;
impl
frame_support::traits::Randomness<
<Runtime as frame_system::Config>::Hash,
BlockNumberFor<Runtime>,
> for RandomnessProvider
{
fn random(
subject: &[u8],
) -> (
<Runtime as frame_system::Config>::Hash,
BlockNumberFor<Runtime>,
) {
let output = <Runtime as frame_system::Config>::Hashing::hash(subject);
let block_number = frame_system::Pallet::<Runtime>::block_number();
(output, block_number)
}
}
Comment on lines +341 to +358
Copy link

Choose a reason for hiding this comment

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

This example is dangerous and we should change it. Suggestion in a comment above.

Copy link
Author

Choose a reason for hiding this comment

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

I could return a zero hash instead.

Copy link

Choose a reason for hiding this comment

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

Ignore my comment, this should be fine. The spec explicit says that this should not be used as a true randomness source.

Copy link

Choose a reason for hiding this comment

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

Sorry for coming back to this, could we append pallet_timestamp::Pallet::<Runtime>::now() to the subject.

And also add a note saying This is just an example, this should not be used as a true randomness source


const BLOCK_GAS_LIMIT: u64 = 75_000_000;
const MAX_POV_SIZE: u64 = 5 * 1024 * 1024;
/// The maximum storage growth per block in bytes.
Expand Down Expand Up @@ -374,6 +395,7 @@ impl pallet_evm::Config for Runtime {
type GasLimitStorageGrowthRatio = GasLimitStorageGrowthRatio;
type Timestamp = Timestamp;
type WeightInfo = pallet_evm::weights::SubstrateWeight<Self>;
type RandomnessProvider = RandomnessProvider;
}

parameter_types! {
Expand Down