-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Refactor module & runtime error handing #2880
Changes from 7 commits
ba48a0a
52c6b90
bd7228f
c0cece1
a93fedd
3039e7c
c5c2e5a
1198fb7
ed20244
1f964d1
83975c0
e03db0c
7e01497
a6c989b
9d2dbbb
31c9c84
6cad33a
ba42e6a
0f01cc4
cce7c08
c7ae1b1
0e424c1
a145f27
ef4eecd
33668d8
d128a1a
a4a8cdc
f4387fb
ef2eaa6
31c998f
d6b94b0
51ec628
88887ee
550c1e0
e8324c2
c147a8e
633a482
b61e137
1ca74ed
3d2c850
8330acf
d41955a
66187b3
7489d3a
57f7958
6e5c3ce
2d9794a
1f5faac
efe953a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -48,18 +48,40 @@ pub mod transaction_validity; | |
| /// Re-export these since they're only "kind of" generic. | ||
| pub use generic::{DigestItem, Digest}; | ||
|
|
||
| /// A message indicating an invalid signature in extrinsic. | ||
| pub const BAD_SIGNATURE: &str = "bad signature in extrinsic"; | ||
|
|
||
| /// Full block error message. | ||
| /// | ||
| /// This allows modules to indicate that given transaction is potentially valid | ||
| /// in the future, but can't be executed in the current state. | ||
| /// Note this error should be returned early in the execution to prevent DoS, | ||
| /// cause the fees are not being paid if this error is returned. | ||
| /// | ||
| /// Example: block gas limit is reached (the transaction can be retried in the next block though). | ||
| pub const BLOCK_FULL: &str = "block size limit is reached"; | ||
| /// Error type | ||
| pub enum Error { | ||
xlc marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| /// Unknown error | ||
| /// This exists only to make implementation easier. Should be avoid as much as possible. | ||
| Unknown(&'static str), | ||
xlc marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| /// Indicating an invalid signature in extrinsic. | ||
| BadSignature, | ||
| /// Full block error. | ||
| /// | ||
| /// This allows modules to indicate that given transaction is potentially valid | ||
| /// in the future, but can't be executed in the current state. | ||
| /// Note this error should be returned early in the execution to prevent DoS, | ||
| /// cause the fees are not being paid if this error is returned. | ||
| /// | ||
| /// Example: block gas limit is reached (the transaction can be retried in the next block though). | ||
| BlockFull | ||
xlc marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| // Exists for for backward compatibility purpose. | ||
| impl From<Error> for &str { | ||
| fn from(err: Error) -> &'static str { | ||
| match err { | ||
| Error::Unknown(val) => val, | ||
| Error::BadSignature => "bad signature in extrinsic", | ||
| Error::BlockFull => "block size limit is reached", | ||
| } | ||
| } | ||
| } | ||
|
|
||
| impl Into<Error> for &'static str { | ||
| fn into(self) -> Error { | ||
| Error::Unknown(self) | ||
| } | ||
| } | ||
|
|
||
| /// Justification type. | ||
| pub type Justification = Vec<u8>; | ||
|
|
@@ -486,23 +508,6 @@ impl From<ed25519::Signature> for AnySignature { | |
| } | ||
| } | ||
|
|
||
| #[derive(Eq, PartialEq, Clone, Copy, Decode)] | ||
| #[cfg_attr(feature = "std", derive(Debug, Serialize))] | ||
| #[repr(u8)] | ||
| /// Outcome of a valid extrinsic application. Capable of being sliced. | ||
| pub enum ApplyOutcome { | ||
| /// Successful application (extrinsic reported no issue). | ||
| Success = 0, | ||
| /// Failed application (extrinsic was probably a no-op other than fees). | ||
| Fail = 1, | ||
| } | ||
|
|
||
| impl codec::Encode for ApplyOutcome { | ||
| fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R { | ||
| f(&[*self as u8]) | ||
| } | ||
| } | ||
|
|
||
| #[derive(Eq, PartialEq, Clone, Copy, Decode)] | ||
| #[cfg_attr(feature = "std", derive(Debug, Serialize))] | ||
| #[repr(u8)] | ||
|
|
@@ -526,6 +531,29 @@ impl codec::Encode for ApplyError { | |
| } | ||
| } | ||
|
|
||
| #[derive(Eq, PartialEq, Clone, Copy, Encode, Decode)] | ||
| #[cfg_attr(feature = "std", derive(Debug, Serialize))] | ||
| /// Reason why a dispatch call failed | ||
| pub struct DispatchError { | ||
| /// Module index, matching the metadata module index | ||
| pub module: i8, // use i8 instead of u8 because u8 is not supported by parity-codec | ||
xlc marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| /// Module specific error value | ||
| pub error: i8, | ||
| /// Optional error message | ||
| #[codec(skip)] | ||
| pub message: Option<&'static str>, | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not just use
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| } | ||
|
|
||
| #[derive(Eq, PartialEq, Clone, Copy, Encode, Decode)] | ||
| #[cfg_attr(feature = "std", derive(Debug, Serialize))] | ||
| /// Outcome of a valid extrinsic application. Capable of being sliced. | ||
| pub enum ApplyOutcome { | ||
bkchr marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| /// Successful application (extrinsic reported no issue). | ||
| Success, | ||
| /// Failed application (extrinsic was probably a no-op other than fees). | ||
| Fail(DispatchError), | ||
| } | ||
|
|
||
| /// Result from attempt to apply an extrinsic. | ||
| pub type ApplyResult = Result<ApplyOutcome, ApplyError>; | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -69,26 +69,44 @@ impl Verify for substrate_primitives::sr25519::Signature { | |||||
| } | ||||||
| } | ||||||
|
|
||||||
| /// EnsureOrigin Error type | ||||||
| pub trait EnsureOriginError { | ||||||
| /// Indicates invalid origin | ||||||
| fn invalid_origin() -> Self; | ||||||
| } | ||||||
|
|
||||||
| /// Some sort of check on the origin is performed by this object. | ||||||
| pub trait EnsureOrigin<OuterOrigin> { | ||||||
| /// A return type. | ||||||
| type Success; | ||||||
| /// Error type | ||||||
| type Error: EnsureOriginError; | ||||||
| /// Perform the origin check. | ||||||
| fn ensure_origin(o: OuterOrigin) -> result::Result<Self::Success, &'static str> { | ||||||
| Self::try_origin(o).map_err(|_| "Invalid origin") | ||||||
| fn ensure_origin(o: OuterOrigin) -> result::Result<Self::Success, Self::Error> { | ||||||
| Self::try_origin(o).map_err(|_| Self::Error::invalid_origin()) | ||||||
| } | ||||||
| /// Perform the origin check. | ||||||
| fn try_origin(o: OuterOrigin) -> result::Result<Self::Success, OuterOrigin>; | ||||||
| } | ||||||
|
|
||||||
| impl EnsureOriginError for () { | ||||||
| fn invalid_origin() -> () { } | ||||||
xlc marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||
| } | ||||||
|
|
||||||
| impl EnsureOriginError for &'static str { | ||||||
| fn invalid_origin() -> &'static str { "Invalid origin" } | ||||||
| } | ||||||
|
|
||||||
| /// Means of changing one type into another in a manner dependent on the source type. | ||||||
| pub trait Lookup { | ||||||
| /// Type to lookup from. | ||||||
| type Source; | ||||||
| /// Type to lookup into. | ||||||
| type Target; | ||||||
| /// Error type | ||||||
| type Error; | ||||||
| /// Attempt a lookup. | ||||||
| fn lookup(&self, s: Self::Source) -> result::Result<Self::Target, &'static str>; | ||||||
| fn lookup(&self, s: Self::Source) -> result::Result<Self::Target, Self::Error>; | ||||||
| } | ||||||
|
|
||||||
| /// Means of changing one type into another in a manner dependent on the source type. | ||||||
|
|
@@ -99,8 +117,10 @@ pub trait StaticLookup { | |||||
| type Source: Codec + Clone + PartialEq + MaybeDebug; | ||||||
| /// Type to lookup into. | ||||||
| type Target; | ||||||
| /// Error type. | ||||||
| type Error: Into<&'static str>; // Into<&'static str> for backward compatibility purpose. | ||||||
| /// Attempt a lookup. | ||||||
| fn lookup(s: Self::Source) -> result::Result<Self::Target, &'static str>; | ||||||
| fn lookup(s: Self::Source) -> result::Result<Self::Target, Self::Error>; | ||||||
| /// Convert from Target back to Source. | ||||||
| fn unlookup(t: Self::Target) -> Self::Source; | ||||||
| } | ||||||
|
|
@@ -111,13 +131,15 @@ pub struct IdentityLookup<T>(PhantomData<T>); | |||||
| impl<T: Codec + Clone + PartialEq + MaybeDebug> StaticLookup for IdentityLookup<T> { | ||||||
| type Source = T; | ||||||
| type Target = T; | ||||||
| fn lookup(x: T) -> result::Result<T, &'static str> { Ok(x) } | ||||||
| type Error = &'static str; | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Should be changed to
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. change to |
||||||
| fn lookup(x: T) -> result::Result<T, Self::Error> { Ok(x) } | ||||||
| fn unlookup(x: T) -> T { x } | ||||||
| } | ||||||
| impl<T> Lookup for IdentityLookup<T> { | ||||||
| type Source = T; | ||||||
| type Target = T; | ||||||
| fn lookup(&self, x: T) -> result::Result<T, &'static str> { Ok(x) } | ||||||
| type Error = &'static str; | ||||||
xlc marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
| fn lookup(&self, x: T) -> result::Result<T, Self::Error> { Ok(x) } | ||||||
| } | ||||||
|
|
||||||
| /// Get the "current" block number. | ||||||
|
|
@@ -701,9 +723,11 @@ pub type DigestItemFor<B> = DigestItem<<<B as Block>::Header as Header>::Hash>; | |||||
| pub trait Checkable<Context>: Sized { | ||||||
| /// Returned if `check` succeeds. | ||||||
| type Checked; | ||||||
| /// Indicates why `check` failed | ||||||
| type Error; | ||||||
|
|
||||||
| /// Check self, given an instance of Context. | ||||||
| fn check(self, c: &Context) -> Result<Self::Checked, &'static str>; | ||||||
| fn check(self, c: &Context) -> Result<Self::Checked, Self::Error>; | ||||||
| } | ||||||
|
|
||||||
| /// A "checkable" piece of information, used by the standard Substrate Executive in order to | ||||||
|
|
@@ -713,15 +737,19 @@ pub trait Checkable<Context>: Sized { | |||||
| pub trait BlindCheckable: Sized { | ||||||
| /// Returned if `check` succeeds. | ||||||
| type Checked; | ||||||
| /// Returned if `check` failed. | ||||||
| type Error; | ||||||
|
|
||||||
| /// Check self. | ||||||
| fn check(self) -> Result<Self::Checked, &'static str>; | ||||||
| fn check(self) -> Result<Self::Checked, Self::Error>; | ||||||
| } | ||||||
|
|
||||||
| // Every `BlindCheckable` is also a `StaticCheckable` for arbitrary `Context`. | ||||||
| impl<T: BlindCheckable, Context> Checkable<Context> for T { | ||||||
| type Checked = <Self as BlindCheckable>::Checked; | ||||||
| fn check(self, _c: &Context) -> Result<Self::Checked, &'static str> { | ||||||
| type Error = <Self as BlindCheckable>::Error; | ||||||
|
|
||||||
| fn check(self, _c: &Context) -> Result<Self::Checked, Self::Error> { | ||||||
| BlindCheckable::check(self) | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
Uh oh!
There was an error while loading. Please reload this page.