tp_inherents/
lib.rs

1// This file is part of Tetcore.
2
3// Copyright (C) 2019-2021 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//! Provides types and traits for creating and checking inherents.
19//!
20//! Each inherent is added to a produced block. Each runtime decides on which inherents it
21//! wants to attach to its blocks. All data that is required for the runtime to create the inherents
22//! is stored in the `InherentData`. This `InherentData` is constructed by the node and given to
23//! the runtime.
24//!
25//! Types that provide data for inherents, should implement `InherentDataProvider` and need to be
26//! registered at `InherentDataProviders`.
27//!
28//! In the runtime, modules need to implement `ProvideInherent` when they can create and/or check
29//! inherents. By implementing `ProvideInherent`, a module is not enforced to create an inherent.
30//! A module can also just check given inherents. For using a module as inherent provider, it needs
31//! to be registered by the `construct_runtime!` macro. The macro documentation gives more
32//! information on how that is done.
33
34#![cfg_attr(not(feature = "std"), no_std)]
35#![warn(missing_docs)]
36
37use codec::{Encode, Decode};
38
39use tetcore_std::{collections::btree_map::{BTreeMap, IntoIter, Entry}, vec::Vec};
40
41#[cfg(feature = "std")]
42use parking_lot::RwLock;
43
44#[cfg(feature = "std")]
45use std::{sync::Arc, format};
46
47/// An error that can occur within the inherent data system.
48#[cfg(feature = "std")]
49#[derive(Debug, Encode, Decode, thiserror::Error)]
50#[error("Inherents: {0}")]
51pub struct Error(String);
52
53#[cfg(feature = "std")]
54impl<T: Into<String>> From<T> for Error {
55	fn from(data: T) -> Error {
56		Self(data.into())
57	}
58}
59
60#[cfg(feature = "std")]
61impl Error {
62	/// Convert this error into a `String`.
63	pub fn into_string(self) -> String {
64		self.0
65	}
66}
67
68/// An error that can occur within the inherent data system.
69#[derive(Encode, tet_core::RuntimeDebug)]
70#[cfg(not(feature = "std"))]
71pub struct Error(&'static str);
72
73#[cfg(not(feature = "std"))]
74impl From<&'static str> for Error {
75	fn from(data: &'static str) -> Error {
76		Self(data)
77	}
78}
79
80/// An identifier for an inherent.
81pub type InherentIdentifier = [u8; 8];
82
83/// Inherent data to include in a block.
84#[derive(Clone, Default, Encode, Decode)]
85pub struct InherentData {
86	/// All inherent data encoded with tetsy-scale-codec and an identifier.
87	data: BTreeMap<InherentIdentifier, Vec<u8>>
88}
89
90impl InherentData {
91	/// Create a new instance.
92	pub fn new() -> Self {
93		Self::default()
94	}
95
96	/// Put data for an inherent into the internal storage.
97	///
98	/// # Return
99	///
100	/// Returns `Ok(())` if the data could be inserted and no data for an inherent with the same
101	/// identifier existed, otherwise an error is returned.
102	///
103	/// Inherent identifiers need to be unique, otherwise decoding of these values will not work!
104	pub fn put_data<I: codec::Encode>(
105		&mut self,
106		identifier: InherentIdentifier,
107		inherent: &I,
108	) -> Result<(), Error> {
109		match self.data.entry(identifier) {
110			Entry::Vacant(entry) => {
111				entry.insert(inherent.encode());
112				Ok(())
113			},
114			Entry::Occupied(_) => {
115				Err("Inherent with same identifier already exists!".into())
116			}
117		}
118	}
119
120	/// Replace the data for an inherent.
121	///
122	/// If it does not exist, the data is just inserted.
123	pub fn replace_data<I: codec::Encode>(
124		&mut self,
125		identifier: InherentIdentifier,
126		inherent: &I,
127	) {
128		self.data.insert(identifier, inherent.encode());
129	}
130
131	/// Returns the data for the requested inherent.
132	///
133	/// # Return
134	///
135	/// - `Ok(Some(I))` if the data could be found and deserialized.
136	/// - `Ok(None)` if the data could not be found.
137	/// - `Err(_)` if the data could be found, but deserialization did not work.
138	pub fn get_data<I: codec::Decode>(
139		&self,
140		identifier: &InherentIdentifier,
141	) -> Result<Option<I>, Error> {
142		match self.data.get(identifier) {
143			Some(inherent) =>
144				I::decode(&mut &inherent[..])
145					.map_err(|_| {
146						"Could not decode requested inherent type!".into()
147					})
148					.map(Some),
149			None => Ok(None)
150		}
151	}
152
153	/// Get the number of inherents in this instance
154	pub fn len(&self) -> usize {
155		self.data.len()
156	}
157}
158
159/// The result of checking inherents.
160///
161/// It either returns okay for all checks, stores all occurred errors or just one fatal error.
162///
163/// When a fatal error occurs, all other errors are removed and the implementation needs to
164/// abort checking inherents.
165#[derive(Encode, Decode, Clone)]
166pub struct CheckInherentsResult {
167	/// Did the check succeed?
168	okay: bool,
169	/// Did we encounter a fatal error?
170	fatal_error: bool,
171	/// We use the `InherentData` to store our errors.
172	errors: InherentData,
173}
174
175impl Default for CheckInherentsResult {
176	fn default() -> Self {
177		Self {
178			okay: true,
179			errors: InherentData::new(),
180			fatal_error: false,
181		}
182	}
183}
184
185impl CheckInherentsResult {
186	/// Create a new instance.
187	pub fn new() -> Self {
188		Self::default()
189	}
190
191	/// Put an error into the result.
192	///
193	/// This makes this result resolve to `ok() == false`.
194	///
195	/// # Parameters
196	///
197	/// - identifier - The identifier of the inherent that generated the error.
198	/// - error - The error that will be encoded.
199	pub fn put_error<E: codec::Encode + IsFatalError>(
200		&mut self,
201		identifier: InherentIdentifier,
202		error: &E,
203	) -> Result<(), Error> {
204		// Don't accept any other error
205		if self.fatal_error {
206			return Err("No other errors are accepted after an hard error!".into())
207		}
208
209		if error.is_fatal_error() {
210			// remove the other errors.
211			self.errors.data.clear();
212		}
213
214		self.errors.put_data(identifier, error)?;
215
216		self.okay = false;
217		self.fatal_error = error.is_fatal_error();
218		Ok(())
219	}
220
221	/// Get an error out of the result.
222	///
223	/// # Return
224	///
225	/// - `Ok(Some(I))` if the error could be found and deserialized.
226	/// - `Ok(None)` if the error could not be found.
227	/// - `Err(_)` if the error could be found, but deserialization did not work.
228	pub fn get_error<E: codec::Decode>(
229		&self,
230		identifier: &InherentIdentifier,
231	) -> Result<Option<E>, Error> {
232		self.errors.get_data(identifier)
233	}
234
235	/// Convert into an iterator over all contained errors.
236	pub fn into_errors(self) -> IntoIter<InherentIdentifier, Vec<u8>> {
237		self.errors.data.into_iter()
238	}
239
240	/// Is this result ok?
241	pub fn ok(&self) -> bool {
242		self.okay
243	}
244
245	/// Is this a fatal error?
246	pub fn fatal_error(&self) -> bool {
247		self.fatal_error
248	}
249}
250
251#[cfg(feature = "std")]
252impl PartialEq for CheckInherentsResult {
253	fn eq(&self, other: &Self) -> bool {
254		self.fatal_error == other.fatal_error &&
255		self.okay == other.okay &&
256		self.errors.data == other.errors.data
257	}
258}
259
260/// All `InherentData` providers.
261#[cfg(feature = "std")]
262#[derive(Clone, Default)]
263pub struct InherentDataProviders {
264	providers: Arc<RwLock<Vec<Box<dyn ProvideInherentData + Send + Sync>>>>,
265}
266
267#[cfg(feature = "std")]
268impl InherentDataProviders {
269	/// Create a new instance.
270	pub fn new() -> Self {
271		Self::default()
272	}
273
274	/// Register an `InherentData` provider.
275	///
276	/// The registration order is preserved and this order will also be used when creating the
277	/// inherent data.
278	///
279	/// # Result
280	///
281	/// Will return an error, if a provider with the same identifier already exists.
282	pub fn register_provider<P: ProvideInherentData + Send + Sync +'static>(
283		&self,
284		provider: P,
285	) -> Result<(), Error> {
286		if self.has_provider(&provider.inherent_identifier()) {
287			Err(
288				format!(
289					"Inherent data provider with identifier {:?} already exists!",
290					&provider.inherent_identifier()
291				).into()
292			)
293		} else {
294			provider.on_register(self)?;
295			self.providers.write().push(Box::new(provider));
296			Ok(())
297		}
298	}
299
300	/// Returns if a provider for the given identifier exists.
301	pub fn has_provider(&self, identifier: &InherentIdentifier) -> bool {
302		self.providers.read().iter().any(|p| p.inherent_identifier() == identifier)
303	}
304
305	/// Create inherent data.
306	pub fn create_inherent_data(&self) -> Result<InherentData, Error> {
307		let mut data = InherentData::new();
308		self.providers.read().iter().try_for_each(|p| {
309			p.provide_inherent_data(&mut data)
310				.map_err(|e| format!("Error for `{:?}`: {:?}", p.inherent_identifier(), e))
311		})?;
312		Ok(data)
313	}
314
315	/// Converts a given encoded error into a `String`.
316	///
317	/// Useful if the implementation encounters an error for an identifier it does not know.
318	pub fn error_to_string(&self, identifier: &InherentIdentifier, error: &[u8]) -> String {
319		let res = self.providers.read().iter().filter_map(|p|
320			if p.inherent_identifier() == identifier {
321				Some(
322					p.error_to_string(error)
323						.unwrap_or_else(|| error_to_string_fallback(identifier))
324				)
325			} else {
326				None
327			}
328		).next();
329
330		match res {
331			Some(res) => res,
332			None => format!(
333				"Error while checking inherent of type \"{}\", but this inherent type is unknown.",
334				String::from_utf8_lossy(identifier)
335			)
336		}
337	}
338}
339
340/// Something that provides inherent data.
341#[cfg(feature = "std")]
342pub trait ProvideInherentData {
343	/// Is called when this inherent data provider is registered at the given
344	/// `InherentDataProviders`.
345	fn on_register(&self, _: &InherentDataProviders) -> Result<(), Error> {
346		Ok(())
347	}
348
349	/// The identifier of the inherent for that data will be provided.
350	fn inherent_identifier(&self) -> &'static InherentIdentifier;
351
352	/// Provide inherent data that should be included in a block.
353	///
354	/// The data should be stored in the given `InherentData` structure.
355	fn provide_inherent_data(&self, inherent_data: &mut InherentData) -> Result<(), Error>;
356
357	/// Convert the given encoded error to a string.
358	///
359	/// If the given error could not be decoded, `None` should be returned.
360	fn error_to_string(&self, error: &[u8]) -> Option<String>;
361}
362
363/// A fallback function, if the decoding of an error fails.
364#[cfg(feature = "std")]
365fn error_to_string_fallback(identifier: &InherentIdentifier) -> String {
366	format!(
367		"Error while checking inherent of type \"{}\", but error could not be decoded.",
368		String::from_utf8_lossy(identifier)
369	)
370}
371
372/// Did we encounter a fatal error while checking an inherent?
373///
374/// A fatal error is everything that fails while checking an inherent error, e.g. the inherent
375/// was not found, could not be decoded etc.
376/// Then there are cases where you not want the inherent check to fail, but report that there is an
377/// action required. For example a timestamp of a block is in the future, the timestamp is still
378/// correct, but it is required to verify the block at a later time again and then the inherent
379/// check will succeed.
380pub trait IsFatalError {
381	/// Is this a fatal error?
382	fn is_fatal_error(&self) -> bool;
383}
384
385/// Auxiliary to make any given error resolve to `is_fatal_error() == true`.
386#[derive(Encode)]
387pub struct MakeFatalError<E: codec::Encode>(E);
388
389impl<E: codec::Encode> From<E> for MakeFatalError<E> {
390	fn from(err: E) -> Self {
391		MakeFatalError(err)
392	}
393}
394
395impl<E: codec::Encode> IsFatalError for MakeFatalError<E> {
396	fn is_fatal_error(&self) -> bool {
397		true
398	}
399}
400
401/// A noble that provides or verifies an inherent extrinsic.
402///
403/// The noble may provide the inherent, verify an inherent, or both provide and verify.
404pub trait ProvideInherent {
405	/// The call type of the noble.
406	type Call;
407	/// The error returned by `check_inherent`.
408	type Error: codec::Encode + IsFatalError;
409	/// The inherent identifier used by this inherent.
410	const INHERENT_IDENTIFIER: self::InherentIdentifier;
411
412	/// Create an inherent out of the given `InherentData`.
413	fn create_inherent(data: &InherentData) -> Option<Self::Call>;
414
415	/// Determines whether this inherent is required in this block.
416	///
417	/// - `Ok(None)` indicates that this inherent is not required in this block. The default
418	/// implementation returns this.
419	///
420	/// - `Ok(Some(e))` indicates that this inherent is required in this block. The
421	/// `impl_outer_inherent!`, will call this function from its `check_extrinsics`.
422	/// If the inherent is not present, it will return `e`.
423	///
424	/// - `Err(_)` indicates that this function failed and further operations should be aborted.
425	///
426	/// CAUTION: This check has a bug when used in nobles that also provide unsigned transactions.
427	/// See https://github.com/tetcoin/tetcore/issues/6243 for details.
428	fn is_inherent_required(_: &InherentData) -> Result<Option<Self::Error>, Self::Error> { Ok(None) }
429
430	/// Check whether the given inherent is valid. Checking the inherent is optional and can be
431	/// omitted by using the default implementation.
432	///
433	/// When checking an inherent, the first parameter represents the inherent that is actually
434	/// included in the block by its author. Whereas the second parameter represents the inherent
435	/// data that the verifying node calculates.
436	fn check_inherent(_: &Self::Call, _: &InherentData) -> Result<(), Self::Error> {
437		Ok(())
438	}
439}
440
441#[cfg(test)]
442mod tests {
443	use super::*;
444	use codec::{Encode, Decode};
445
446	const TEST_INHERENT_0: InherentIdentifier = *b"testinh0";
447	const TEST_INHERENT_1: InherentIdentifier = *b"testinh1";
448
449	#[derive(Encode)]
450	struct NoFatalError<E: codec::Encode>(E);
451	impl<E: codec::Encode> IsFatalError for NoFatalError<E> {
452		fn is_fatal_error(&self) -> bool {
453			false
454		}
455	}
456
457	#[test]
458	fn inherent_data_encodes_and_decodes() {
459		let inherent_0 = vec![1, 2, 3];
460		let inherent_1: u32 = 7;
461
462		let mut data = InherentData::new();
463		data.put_data(TEST_INHERENT_0, &inherent_0).unwrap();
464		data.put_data(TEST_INHERENT_1, &inherent_1).unwrap();
465
466		let encoded = data.encode();
467
468		let decoded = InherentData::decode(&mut &encoded[..]).unwrap();
469
470		assert_eq!(decoded.get_data::<Vec<u32>>(&TEST_INHERENT_0).unwrap().unwrap(), inherent_0);
471		assert_eq!(decoded.get_data::<u32>(&TEST_INHERENT_1).unwrap().unwrap(), inherent_1);
472	}
473
474	#[test]
475	fn adding_same_inherent_returns_an_error() {
476		let mut data = InherentData::new();
477		data.put_data(TEST_INHERENT_0, &8).unwrap();
478		assert!(data.put_data(TEST_INHERENT_0, &10).is_err());
479	}
480
481	#[derive(Clone)]
482	struct TestInherentDataProvider {
483		registered: Arc<RwLock<bool>>,
484	}
485
486	impl TestInherentDataProvider {
487		fn new() -> Self {
488			let inst = Self {
489				registered: Default::default(),
490			};
491
492			// just make sure
493			assert!(!inst.is_registered());
494
495			inst
496		}
497
498		fn is_registered(&self) -> bool {
499			*self.registered.read()
500		}
501	}
502
503	const ERROR_TO_STRING: &str = "Found error!";
504
505	impl ProvideInherentData for TestInherentDataProvider {
506		fn on_register(&self, _: &InherentDataProviders) -> Result<(), Error> {
507			*self.registered.write() = true;
508			Ok(())
509		}
510
511		fn inherent_identifier(&self) -> &'static InherentIdentifier {
512			&TEST_INHERENT_0
513		}
514
515		fn provide_inherent_data(&self, data: &mut InherentData) -> Result<(), Error> {
516			data.put_data(TEST_INHERENT_0, &42)
517		}
518
519		fn error_to_string(&self, _: &[u8]) -> Option<String> {
520			Some(ERROR_TO_STRING.into())
521		}
522	}
523
524	#[test]
525	fn registering_inherent_provider() {
526		let provider = TestInherentDataProvider::new();
527		let providers = InherentDataProviders::new();
528
529		providers.register_provider(provider.clone()).unwrap();
530		assert!(provider.is_registered());
531		assert!(providers.has_provider(provider.inherent_identifier()));
532
533		// Second time should fail
534		assert!(providers.register_provider(provider.clone()).is_err());
535	}
536
537	#[test]
538	fn create_inherent_data_from_all_providers() {
539		let provider = TestInherentDataProvider::new();
540		let providers = InherentDataProviders::new();
541
542		providers.register_provider(provider.clone()).unwrap();
543		assert!(provider.is_registered());
544
545		let inherent_data = providers.create_inherent_data().unwrap();
546
547		assert_eq!(
548			inherent_data.get_data::<u32>(provider.inherent_identifier()).unwrap().unwrap(),
549			42u32
550		);
551	}
552
553	#[test]
554	fn encoded_error_to_string() {
555		let provider = TestInherentDataProvider::new();
556		let providers = InherentDataProviders::new();
557
558		providers.register_provider(provider.clone()).unwrap();
559		assert!(provider.is_registered());
560
561		assert_eq!(
562			&providers.error_to_string(&TEST_INHERENT_0, &[1, 2]), ERROR_TO_STRING
563		);
564
565		assert!(
566			providers
567				.error_to_string(&TEST_INHERENT_1, &[1, 2])
568				.contains("inherent type is unknown")
569		);
570	}
571
572	#[test]
573	fn check_inherents_result_encodes_and_decodes() {
574		let mut result = CheckInherentsResult::new();
575		assert!(result.ok());
576
577		result.put_error(TEST_INHERENT_0, &NoFatalError(2u32)).unwrap();
578		assert!(!result.ok());
579		assert!(!result.fatal_error());
580
581		let encoded = result.encode();
582
583		let decoded = CheckInherentsResult::decode(&mut &encoded[..]).unwrap();
584
585		assert_eq!(decoded.get_error::<u32>(&TEST_INHERENT_0).unwrap().unwrap(), 2);
586		assert!(!decoded.ok());
587		assert!(!decoded.fatal_error());
588	}
589
590	#[test]
591	fn check_inherents_result_removes_other_errors_on_fatal_error() {
592		let mut result = CheckInherentsResult::new();
593		assert!(result.ok());
594
595		result.put_error(TEST_INHERENT_0, &NoFatalError(2u32)).unwrap();
596		assert!(!result.ok());
597		assert!(!result.fatal_error());
598
599		result.put_error(TEST_INHERENT_1, &MakeFatalError(4u32)).unwrap();
600		assert!(!result.ok());
601		assert!(result.fatal_error());
602
603		assert!(result.put_error(TEST_INHERENT_0, &NoFatalError(5u32)).is_err());
604
605		result.into_errors().for_each(|(i, e)| match i {
606			TEST_INHERENT_1 => assert_eq!(u32::decode(&mut &e[..]).unwrap(), 4),
607			_ => panic!("There should be no other error!"),
608		});
609	}
610}