-
Notifications
You must be signed in to change notification settings - Fork 19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Timestamp Inherent #100
Timestamp Inherent #100
Changes from 117 commits
771d02e
36b5956
dfa2fc7
86b2589
72d8d66
e9f039b
9b86b72
3b57339
821d99e
75d3718
78f9ee5
698b725
7721424
04d0f19
97c0530
a0d806e
ac2d722
39d9001
95f3788
01bdac4
d26afb3
eace947
e73fa69
375c9ce
5bdd2a1
64f0630
9b2a00c
5e4ad6b
eb6f8e2
059a89f
d172b20
858d9f3
f3710e1
1ec0bef
b3c74fa
fbcc042
ffa2c9a
b729e6d
0545d85
f8983e7
632787e
8ecdba2
8ed0943
159df78
705624d
4a97938
2d395a0
c4b9fed
e818e8c
2f9441b
05a98ff
fb2c449
ead4e98
fb19665
992f0e0
19881d5
3c4b7f6
475878d
dd8d4bb
aaea5f9
4a8cdab
7e76ab8
f7f31d1
ec19f60
fc7728c
d4bf5c4
276fec3
355d748
6af2af8
57b3fd5
63c00b8
d5b405f
dd5cb36
68cfc6e
c3dacc3
7c04760
d1afb63
ca8fdbe
48a9a15
fc1bef3
0bca1a7
68ca36c
78e08aa
b2820ea
3bac6b6
732bd29
6e3e073
b05377f
2dcc393
9316d88
004bff8
47eacf6
3833626
bbeb545
6df89a6
f4b2469
3168eb2
08204fe
33b208e
88b7b85
6686fa4
87435da
6c34da7
3d6a337
7a2257b
3891357
d8220ab
31986e2
f25cf1b
c2bd33a
80aaa80
51570b6
ebde077
ce0f348
c2026d0
aa27f8f
96c6987
6569eba
057cdb7
7377d96
4f1376e
81a57a3
2df4be6
f3c88ec
1021312
3805b52
6409334
8c09593
730028a
8e7350e
e0d629d
d60a841
52b2f85
87ee4dc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,20 +32,35 @@ pub fn aggregate(_: TokenStream, body: TokenStream) -> TokenStream { | |
) | ||
}); | ||
let variants = variant_type_pairs.clone().map(|(v, _t)| v); | ||
let variants2 = variants.clone(); | ||
let inner_types = variant_type_pairs.map(|(_v, t)| t); | ||
let inner_types2 = inner_types.clone(); | ||
|
||
let output = quote! { | ||
// First keep the original code in tact | ||
#original_code | ||
|
||
// Now write all the From impls | ||
// Now write all the wrapping From impls | ||
#( | ||
impl From<#inner_types> for #outer_type { | ||
fn from(b: #inner_types) -> Self { | ||
Self::#variants(b) | ||
} | ||
} | ||
)* | ||
|
||
// Finally write all the un-wrapping From impls | ||
#( | ||
impl From<#outer_type> for #inner_types2 { | ||
fn from(a: #outer_type) -> Self { | ||
if let #outer_type::#variants2(b) = a { | ||
b | ||
} else { | ||
panic!("wrong type or something...") | ||
} | ||
} | ||
} | ||
)* | ||
}; | ||
|
||
output.into() | ||
|
@@ -115,12 +130,28 @@ pub fn tuxedo_constraint_checker(attrs: TokenStream, body: TokenStream) -> Token | |
let variants = variant_type_pairs.clone().map(|(v, _t)| v); | ||
let inner_types = variant_type_pairs.map(|(_v, t)| t); | ||
|
||
let vis = ast.vis; | ||
// Set up the names of the new associated types. | ||
let mut error_type_name = outer_type.to_string(); | ||
error_type_name.push_str("Error"); | ||
let error_type = Ident::new(&error_type_name, outer_type.span()); | ||
let inner_types = inner_types.clone(); | ||
|
||
let mut inherent_hooks_name = outer_type.to_string(); | ||
inherent_hooks_name.push_str("InherentHooks"); | ||
let inherent_hooks = Ident::new(&inherent_hooks_name, outer_type.span()); | ||
|
||
let vis = ast.vis; | ||
|
||
// TODO there must be a better way to do this, right? | ||
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. 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. The first problem here is that the value can't be cloned in the quote macro (as far as I know, if it would be possible with some magic trick then the solution would be obvious) so all the clones need to be done before the macro, and that repeated code is the result. An easy solution is to involve a macro_rules to avoid repeat all the syntax but the inner problem is that inside macro_rules identifiers can't be created, then I came up with two solutions:
macro multiple_assign {
($($num:literal),* = $var:ident) => {
paste!{ $(let [<$var $num>] = $var.clone();)* }
}
}
multiple_assign!(2,3,4,6 = inner_types);
multiple_assign!(2,3,4,5,6 = variants); the final code is not so smaller than the previous one but is more scalable if the required copies of inner_types and variants will grow in the future
JoshOrndorff marked this conversation as resolved.
Show resolved
Hide resolved
|
||
let inner_types2 = inner_types.clone(); | ||
let inner_types3 = inner_types.clone(); | ||
let inner_types4 = inner_types.clone(); | ||
let inner_types6 = inner_types.clone(); | ||
let variants2 = variants.clone(); | ||
let variants3 = variants.clone(); | ||
let variants4 = variants.clone(); | ||
let variants5 = variants.clone(); | ||
let variants6 = variants.clone(); | ||
|
||
let output = quote! { | ||
// Preserve the original enum, and write the From impls | ||
#[tuxedo_core::aggregate] | ||
|
@@ -138,9 +169,84 @@ pub fn tuxedo_constraint_checker(attrs: TokenStream, body: TokenStream) -> Token | |
)* | ||
} | ||
|
||
/// This type is generated by the `#[tuxedo_constraint_checker]` macro. | ||
/// It is a combined set of inherent hooks for the inherent hooks of each individual checker. | ||
/// | ||
/// This type is accessible downstream as `<OuterConstraintChecker as ConstraintChecker>::InherentHooks` | ||
#[derive(Debug, scale_info::TypeInfo)] | ||
#vis enum #inherent_hooks { | ||
#( | ||
#variants2(<#inner_types2 as tuxedo_core::ConstraintChecker<#verifier>>::InherentHooks), | ||
)* | ||
} | ||
|
||
impl tuxedo_core::inherents::InherentInternal<#verifier, #outer_type> for #inherent_hooks { | ||
|
||
fn create_inherents( | ||
authoring_inherent_data: &InherentData, | ||
previous_inherents: Vec<(tuxedo_core::types::Transaction<#verifier, #outer_type>, sp_core::H256)>, | ||
) -> Vec<tuxedo_core::types::Transaction<#verifier, #outer_type>> { | ||
|
||
let mut all_inherents = Vec::new(); | ||
|
||
#( | ||
{ | ||
// Filter the previous inherents down to just the ones that came from this piece | ||
let previous_inherents = previous_inherents | ||
.iter() | ||
.filter_map(|(tx, hash)| { | ||
match tx.checker { | ||
#outer_type::#variants3(ref inner_checker) => Some((tx.transform::<#inner_types3>(), *hash )), | ||
_ => None, | ||
} | ||
}) | ||
.collect(); | ||
|
||
let inherents = <#inner_types3 as tuxedo_core::ConstraintChecker<#verifier>>::InherentHooks::create_inherents(authoring_inherent_data, previous_inherents) | ||
.iter() | ||
.map(|tx| tx.transform::<#outer_type>()) | ||
.collect::<Vec<_>>(); | ||
all_inherents.extend(inherents); | ||
} | ||
)* | ||
|
||
// Return the aggregate of all inherent extrinsics from all constituent constraint checkers. | ||
all_inherents | ||
} | ||
|
||
fn check_inherents( | ||
importing_inherent_data: &sp_inherents::InherentData, | ||
inherents: Vec<tuxedo_core::types::Transaction<#verifier, #outer_type>>, | ||
result: &mut sp_inherents::CheckInherentsResult, | ||
) { | ||
#( | ||
let relevant_inherents: Vec<tuxedo_core::types::Transaction<#verifier, #inner_types4>> = inherents | ||
.iter() | ||
.filter_map(|tx| { | ||
match tx.checker { | ||
#outer_type::#variants4(ref inner_checker) => Some(tx.transform::<#inner_types4>()), | ||
_ => None, | ||
} | ||
}) | ||
.collect(); | ||
|
||
<#inner_types4 as tuxedo_core::ConstraintChecker<#verifier>>::InherentHooks::check_inherents(importing_inherent_data, relevant_inherents, result); | ||
|
||
// According to https://paritytech.github.io/polkadot-sdk/master/sp_inherents/struct.CheckInherentsResult.html | ||
// "When a fatal error occurs, all other errors are removed and the implementation needs to abort checking inherents." | ||
if result.fatal_error() { | ||
return; | ||
} | ||
)* | ||
} | ||
|
||
} | ||
|
||
impl tuxedo_core::ConstraintChecker<#verifier> for #outer_type { | ||
type Error = #error_type; | ||
|
||
type InherentHooks = #inherent_hooks; | ||
|
||
fn check ( | ||
&self, | ||
inputs: &[tuxedo_core::types::Output<#verifier>], | ||
|
@@ -149,10 +255,20 @@ pub fn tuxedo_constraint_checker(attrs: TokenStream, body: TokenStream) -> Token | |
) -> Result<TransactionPriority, Self::Error> { | ||
match self { | ||
#( | ||
Self::#variants2(inner) => inner.check(inputs, peeks, outputs).map_err(|e| Self::Error::#variants2(e)), | ||
Self::#variants5(inner) => inner.check(inputs, peeks, outputs).map_err(|e| Self::Error::#variants5(e)), | ||
)* | ||
} | ||
} | ||
|
||
fn is_inherent(&self) -> bool { | ||
match self { | ||
#( | ||
Self::#variants6(inner) => <#inner_types6 as tuxedo_core::ConstraintChecker<#verifier>>::is_inherent(inner), | ||
)* | ||
} | ||
|
||
} | ||
|
||
} | ||
}; | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like this double expect at all. This method returns a Result, so please update this accordingly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've improved the panic messages in 6569eba so that is at least a step in the right direction. If this can be improved more I will need some guided help.
I don't think that's true. Here's my understanding. Although the types are complex, so correct me if I'm wrong.
This function with the
let parent_block = ...
line you quoted is a closure that is being passed in to start the Aura worker. That closure does not return aResult
. Rather, it returns an async closure that will, itself, eventually return aResult
.https://paritytech.github.io/polkadot-sdk/master/sp_inherents/trait.CreateInherentDataProviders.html
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It took a while, but I found where this is used.
https://github.com/paritytech/polkadot-sdk/blob/7aace06b3d653529ab992c8ff96571d54bf00a36/substrate/client/consensus/slots/src/slots.rs#L154
It logs the error and tries again next slot, so it might not like a panic
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitely we will not be able to author a block if the database does not know about the previous block. What do you suggest to improve this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was trying earlier to make this return an error when needed, instead of panicking. I wanted to do someting like:
There was some issues with the closure being async, and I'm not familiar with that, so please try to make this work without spending too much time on it, otherwise it's fine to leave it like this.