Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Introduce entropy function into frame System #14149

Merged
merged 1 commit into from
May 15, 2023
Merged
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
14 changes: 14 additions & 0 deletions frame/system/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@

#[cfg(feature = "std")]
use serde::Serialize;
use sp_io::hashing::blake2_256;
#[cfg(feature = "runtime-benchmarks")]
use sp_runtime::traits::TrailingZeroInput;
use sp_runtime::{
Expand Down Expand Up @@ -1316,6 +1317,8 @@ impl<T: Config> Pallet<T> {
// populate environment
ExecutionPhase::<T>::put(Phase::Initialization);
storage::unhashed::put(well_known_keys::EXTRINSIC_INDEX, &0u32);
let entropy = (b"frame_system::initialize", parent_hash).using_encoded(blake2_256);
storage::unhashed::put(well_known_keys::INTRABLOCK_ENTROPY, &entropy[..]);
Copy link
Member

@ggwpez ggwpez May 15, 2023

Choose a reason for hiding this comment

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

Suggested change
storage::unhashed::put(well_known_keys::INTRABLOCK_ENTROPY, &entropy[..]);
storage::unhashed::put_raw(well_known_keys::INTRABLOCK_ENTROPY, &entropy[..]);

Otherwise put encodes again and pretends the length, so it looses one byte of entropy when only reading the first 32 bytes.

Copy link
Contributor

@liamaharon liamaharon May 15, 2023

Choose a reason for hiding this comment

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

Just linking to PR addressing this: #14152

Copy link
Member

Choose a reason for hiding this comment

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

fixed lengths arrays are not prepended with its length.

Copy link
Member

@ggwpez ggwpez May 16, 2023

Choose a reason for hiding this comment

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

It is a slice though, because of the [..] i assume.

Copy link
Member

Choose a reason for hiding this comment

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

Good point 🙈

<Number<T>>::put(number);
<Digest<T>>::put(digest);
<ParentHash<T>>::put(parent_hash);
Expand Down Expand Up @@ -1365,6 +1368,7 @@ impl<T: Config> Pallet<T> {
);
ExecutionPhase::<T>::kill();
AllExtrinsicsLen::<T>::kill();
storage::unhashed::kill(well_known_keys::INTRABLOCK_ENTROPY);

// The following fields
//
Expand Down Expand Up @@ -1633,6 +1637,16 @@ impl<T: Config> Pallet<T> {
}
}

/// Returns a 32 byte datum which is guaranteed to be universally unique. `entropy` is provided
/// as a facility to reduce the potential for precalculating results.
pub fn unique(entropy: impl Encode) -> [u8; 32] {
let mut last = [0u8; 32];
sp_io::storage::read(well_known_keys::INTRABLOCK_ENTROPY, &mut last[..], 0);
let next = (b"frame_system::unique", entropy, last).using_encoded(blake2_256);
sp_io::storage::set(well_known_keys::INTRABLOCK_ENTROPY, &next.encode());
next
}

/// Event handler which registers a provider when created.
pub struct Provider<T>(PhantomData<T>);
impl<T: Config> HandleLifetime<T::AccountId> for Provider<T> {
Expand Down
21 changes: 21 additions & 0 deletions frame/system/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,27 @@ fn origin_works() {
assert_eq!(x.unwrap(), RawOrigin::<u64>::Signed(1u64));
}

#[test]
fn unique_datum_works() {
new_test_ext().execute_with(|| {
System::initialize(&1, &[0u8; 32].into(), &Default::default());
assert!(sp_io::storage::exists(well_known_keys::INTRABLOCK_ENTROPY));

let h1 = unique(b"");
let h2 = unique(b"");
assert_ne!(h1, h2);

let h3 = unique(b"Hello");
assert_ne!(h2, h3);

let h4 = unique(b"Hello");
assert_ne!(h3, h4);

System::finalize();
assert!(!sp_io::storage::exists(well_known_keys::INTRABLOCK_ENTROPY));
});
}

#[test]
fn stored_map_works() {
new_test_ext().execute_with(|| {
Expand Down
3 changes: 3 additions & 0 deletions primitives/storage/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,9 @@ pub mod well_known_keys {
/// Encodes to `0x3a65787472696e7369635f696e646578`.
pub const EXTRINSIC_INDEX: &[u8] = b":extrinsic_index";

/// Current intra-block entropy (a universally unique `[u8; 32]` value) is stored here.
pub const INTRABLOCK_ENTROPY: &[u8] = b":intrablock_entropy";

/// Prefix of child storage keys.
pub const CHILD_STORAGE_KEY_PREFIX: &[u8] = b":child_storage:";

Expand Down