diff --git a/prdoc/pr_10235.prdoc b/prdoc/pr_10235.prdoc new file mode 100644 index 0000000000000..34df18a38b603 --- /dev/null +++ b/prdoc/pr_10235.prdoc @@ -0,0 +1,12 @@ +title: 'offchain-worker: Do not intialize the entire `System` again' +doc: +- audience: Runtime Dev + description: |- + When calling `offchain-worker` we were initializing the entire `System` again with the same block we are running on top of. However, with [the change to require strictly increasing block numbers](https://github.com/paritytech/polkadot-sdk/pull/10180) the offchain-worker was failing. This is now solved by just registering the missing digests. The rest of the changes done by `initialize` are not important for offchain workers. + + The pull request ensures that we are actually testing this behavior of the offchain worker now. +crates: +- name: frame-executive + bump: patch +- name: frame-system + bump: patch diff --git a/substrate/frame/executive/src/lib.rs b/substrate/frame/executive/src/lib.rs index 1919f890cdf15..60cde231a8c00 100644 --- a/substrate/frame/executive/src/lib.rs +++ b/substrate/frame/executive/src/lib.rs @@ -953,7 +953,14 @@ where // OffchainWorker RuntimeApi should skip initialization. let digests = header.digest().clone(); - >::initialize(header.number(), header.parent_hash(), &digests); + // Let's deposit all the logs we are not yet aware of. These are the logs set by the `node`. + let existing_digest = frame_system::Pallet::::digest(); + for digest in digests.logs().iter().filter(|d| !existing_digest.logs.contains(d)) { + frame_system::Pallet::::deposit_log(digest.clone()); + } + + // Initialize the intra block entropy, which is maybe used by offchain workers. + frame_system::Pallet::::initialize_intra_block_entropy(header.parent_hash()); // Frame system only inserts the parent hash into the block hashes as normally we don't know // the hash for the header before. However, here we are aware of the hash and we can add it diff --git a/substrate/frame/executive/src/tests.rs b/substrate/frame/executive/src/tests.rs index d8d0836384054..0569f8eb52bf0 100644 --- a/substrate/frame/executive/src/tests.rs +++ b/substrate/frame/executive/src/tests.rs @@ -1113,7 +1113,14 @@ fn all_weights_are_recorded_correctly() { fn offchain_worker_works_as_expected() { new_test_ext(1).execute_with(|| { let parent_hash = sp_core::H256::from([69u8; 32]); + + // Emulate block production before running the offchain worker. + System::initialize(&1, &parent_hash, &Digest::default()); + System::finalize(); + let mut digest = Digest::default(); + // As `Seal` is added by the node after the block was build, it was not part of + // `System::initialize` above. digest.push(DigestItem::Seal([1, 2, 3, 4], vec![5, 6, 7, 8])); let header = Header::new(1, H256::default(), H256::default(), parent_hash, digest.clone()); diff --git a/substrate/frame/system/src/lib.rs b/substrate/frame/system/src/lib.rs index c0729d47a6efe..9d80e6ec338d2 100644 --- a/substrate/frame/system/src/lib.rs +++ b/substrate/frame/system/src/lib.rs @@ -1918,8 +1918,7 @@ impl Pallet { // populate environment ExecutionPhase::::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_raw(well_known_keys::INTRABLOCK_ENTROPY, &entropy[..]); + Self::initialize_intra_block_entropy(parent_hash); >::put(number); >::put(digest); >::put(parent_hash); @@ -1929,6 +1928,14 @@ impl Pallet { BlockWeight::::kill(); } + /// Initialize [`INTRABLOCK_ENTROPY`](well_known_keys::INTRABLOCK_ENTROPY). + /// + /// Normally this is called internally [`initialize`](Self::initialize) at block initiation. + pub fn initialize_intra_block_entropy(parent_hash: &T::Hash) { + let entropy = (b"frame_system::initialize", parent_hash).using_encoded(blake2_256); + storage::unhashed::put_raw(well_known_keys::INTRABLOCK_ENTROPY, &entropy[..]); + } + /// Log the entire resouce usage report up until this point. /// /// Uses `crate::LOG_TARGET`, level `debug` and prints the weight and block length usage. diff --git a/substrate/test-utils/runtime/src/lib.rs b/substrate/test-utils/runtime/src/lib.rs index aace5b3e18eaa..a04b05021bb46 100644 --- a/substrate/test-utils/runtime/src/lib.rs +++ b/substrate/test-utils/runtime/src/lib.rs @@ -742,6 +742,7 @@ impl_runtime_apis! { }.into(), ); sp_io::offchain::submit_transaction(ext.encode()).unwrap(); + Executive::offchain_worker(header); } }