Skip to content

Commit 9a18761

Browse files
authored
Cleaner separation of Verifier / Constraint Cheker duties (#188)
1 parent 8a2f661 commit 9a18761

File tree

20 files changed

+409
-322
lines changed

20 files changed

+409
-322
lines changed

tuxedo-core/aggregator/src/lib.rs

+52-61
Original file line numberDiff line numberDiff line change
@@ -101,11 +101,19 @@ pub fn tuxedo_verifier(_: TokenStream, body: TokenStream) -> TokenStream {
101101
let mut redeemer_type_name = outer_type.to_string();
102102
redeemer_type_name.push_str("Redeemer");
103103
let redeemer_type = Ident::new(&redeemer_type_name, outer_type.span());
104+
let type_for_new_unspendable = inner_types
105+
.clone()
106+
.next()
107+
.expect("At least one verifier variant expected.");
104108

105109
// TODO there must be a better way to do this, right?
106110
let inner_types2 = inner_types.clone();
107111
let variants2 = variants.clone();
108112
let variants3 = variants.clone();
113+
let variant_for_new_unspendable = variants
114+
.clone()
115+
.next()
116+
.expect("At least one verifier variant expected.");
109117

110118
let as_variants = variants.clone().map(|v| {
111119
let s = format!("as_{}", v);
@@ -160,6 +168,14 @@ pub fn tuxedo_verifier(_: TokenStream, body: TokenStream) -> TokenStream {
160168
)*
161169
}
162170
}
171+
172+
// The aggregation macro assumes that the first variant is able to produce a new unspendable instance.
173+
// In the future this could be made nicer (but maybe not worth the complexity) by allowing an additional
174+
// annotation to the one that can be used as unspendable eg `#[unspendable]`
175+
// If this ever becomes a challenge just add an explicit `Unspendable` variant first.
176+
fn new_unspendable() -> Option<Self> {
177+
#type_for_new_unspendable::new_unspendable().map(|inner| Self::#variant_for_new_unspendable(inner))
178+
}
163179
}
164180
};
165181
output.into()
@@ -173,9 +189,8 @@ pub fn tuxedo_verifier(_: TokenStream, body: TokenStream) -> TokenStream {
173189
/// just like this original enum. however, the contained values in the error enum are of the corresponding types
174190
/// for the inner constraint checker.
175191
#[proc_macro_attribute]
176-
pub fn tuxedo_constraint_checker(attrs: TokenStream, body: TokenStream) -> TokenStream {
192+
pub fn tuxedo_constraint_checker(_attrs: TokenStream, body: TokenStream) -> TokenStream {
177193
let ast = parse_macro_input!(body as ItemEnum);
178-
let verifier = parse_macro_input!(attrs as Ident);
179194
let original_code = ast.clone();
180195

181196
let outer_type = ast.ident;
@@ -204,23 +219,16 @@ pub fn tuxedo_constraint_checker(attrs: TokenStream, body: TokenStream) -> Token
204219
error_type_name.push_str("Error");
205220
let error_type = Ident::new(&error_type_name, outer_type.span());
206221

207-
let mut inherent_hooks_name = outer_type.to_string();
208-
inherent_hooks_name.push_str("InherentHooks");
209-
let inherent_hooks = Ident::new(&inherent_hooks_name, outer_type.span());
210-
211222
let vis = ast.vis;
212223

213224
// TODO there must be a better way to do this, right?
214225
let inner_types2 = inner_types.clone();
215226
let inner_types3 = inner_types.clone();
216227
let inner_types4 = inner_types.clone();
217-
let inner_types6 = inner_types.clone();
218-
let inner_types7 = inner_types.clone();
219228
let variants2 = variants.clone();
220229
let variants3 = variants.clone();
221230
let variants4 = variants.clone();
222231
let variants5 = variants.clone();
223-
let variants6 = variants.clone();
224232

225233
let output = quote! {
226234
// Preserve the original enum, and write the From impls
@@ -235,27 +243,39 @@ pub fn tuxedo_constraint_checker(attrs: TokenStream, body: TokenStream) -> Token
235243
#[derive(Debug)]
236244
#vis enum #error_type {
237245
#(
238-
#variants(<#inner_types as tuxedo_core::ConstraintChecker<#verifier>>::Error),
246+
#variants(<#inner_types as tuxedo_core::ConstraintChecker>::Error),
239247
)*
240248
}
241249

242-
/// This type is generated by the `#[tuxedo_constraint_checker]` macro.
243-
/// It is a combined set of inherent hooks for the inherent hooks of each individual checker.
244-
///
245-
/// This type is accessible downstream as `<OuterConstraintChecker as ConstraintChecker>::InherentHooks`
246-
#[derive(Debug, scale_info::TypeInfo)]
247-
#vis enum #inherent_hooks {
248-
#(
249-
#variants2(<#inner_types2 as tuxedo_core::ConstraintChecker<#verifier>>::InherentHooks),
250-
)*
251-
}
250+
impl tuxedo_core::ConstraintChecker for #outer_type {
251+
type Error = #error_type;
252252

253-
impl tuxedo_core::inherents::InherentInternal<#verifier, #outer_type> for #inherent_hooks {
253+
fn check (
254+
&self,
255+
inputs: &[tuxedo_core::dynamic_typing::DynamicallyTypedData],
256+
peeks: &[tuxedo_core::dynamic_typing::DynamicallyTypedData],
257+
outputs: &[tuxedo_core::dynamic_typing::DynamicallyTypedData],
258+
) -> Result<TransactionPriority, Self::Error> {
259+
match self {
260+
#(
261+
Self::#variants5(inner) => inner.check(inputs, peeks, outputs).map_err(|e| Self::Error::#variants5(e)),
262+
)*
263+
}
264+
}
265+
266+
fn is_inherent(&self) -> bool {
267+
match self {
268+
#(
269+
Self::#variants2(inner) => inner.is_inherent(),
270+
)*
271+
}
254272

255-
fn create_inherents(
273+
}
274+
275+
fn create_inherents<V: tuxedo_core::Verifier>(
256276
authoring_inherent_data: &InherentData,
257-
previous_inherents: Vec<(tuxedo_core::types::Transaction<#verifier, #outer_type>, sp_core::H256)>,
258-
) -> Vec<tuxedo_core::types::Transaction<#verifier, #outer_type>> {
277+
previous_inherents: Vec<(tuxedo_core::types::Transaction<V, #outer_type>, sp_core::H256)>,
278+
) -> Vec<tuxedo_core::types::Transaction<V, #outer_type>> {
259279

260280
let mut all_inherents = Vec::new();
261281

@@ -272,7 +292,7 @@ pub fn tuxedo_constraint_checker(attrs: TokenStream, body: TokenStream) -> Token
272292
})
273293
.collect();
274294

275-
let inherents = <#inner_types3 as tuxedo_core::ConstraintChecker<#verifier>>::InherentHooks::create_inherents(authoring_inherent_data, previous_inherents)
295+
let inherents = <#inner_types3 as tuxedo_core::ConstraintChecker>::create_inherents(authoring_inherent_data, previous_inherents)
276296
.iter()
277297
.map(|tx| tx.transform::<#outer_type>())
278298
.collect::<Vec<_>>();
@@ -284,13 +304,13 @@ pub fn tuxedo_constraint_checker(attrs: TokenStream, body: TokenStream) -> Token
284304
all_inherents
285305
}
286306

287-
fn check_inherents(
307+
fn check_inherents<V: tuxedo_core::Verifier>(
288308
importing_inherent_data: &sp_inherents::InherentData,
289-
inherents: Vec<tuxedo_core::types::Transaction<#verifier, #outer_type>>,
309+
inherents: Vec<tuxedo_core::types::Transaction<V, #outer_type>>,
290310
result: &mut sp_inherents::CheckInherentsResult,
291311
) {
292312
#(
293-
let relevant_inherents: Vec<tuxedo_core::types::Transaction<#verifier, #inner_types4>> = inherents
313+
let relevant_inherents: Vec<tuxedo_core::types::Transaction<V, #inner_types4>> = inherents
294314
.iter()
295315
.filter_map(|tx| {
296316
match tx.checker {
@@ -300,7 +320,7 @@ pub fn tuxedo_constraint_checker(attrs: TokenStream, body: TokenStream) -> Token
300320
})
301321
.collect();
302322

303-
<#inner_types4 as tuxedo_core::ConstraintChecker<#verifier>>::InherentHooks::check_inherents(importing_inherent_data, relevant_inherents, result);
323+
<#inner_types4 as tuxedo_core::ConstraintChecker>::check_inherents(importing_inherent_data, relevant_inherents, result);
304324

305325
// According to https://paritytech.github.io/polkadot-sdk/master/sp_inherents/struct.CheckInherentsResult.html
306326
// "When a fatal error occurs, all other errors are removed and the implementation needs to abort checking inherents."
@@ -311,12 +331,12 @@ pub fn tuxedo_constraint_checker(attrs: TokenStream, body: TokenStream) -> Token
311331
}
312332

313333
#[cfg(feature = "std")]
314-
fn genesis_transactions() -> Vec<tuxedo_core::types::Transaction<#verifier, #outer_type>> {
315-
let mut all_transactions: Vec<tuxedo_core::types::Transaction<#verifier, #outer_type>> = Vec::new();
334+
fn genesis_transactions<V: tuxedo_core::Verifier>() -> Vec<tuxedo_core::types::Transaction<V, #outer_type>> {
335+
let mut all_transactions: Vec<tuxedo_core::types::Transaction<V, #outer_type>> = Vec::new();
316336

317337
#(
318338
let transactions =
319-
<<#inner_types6 as tuxedo_core::ConstraintChecker<#verifier>>::InherentHooks as tuxedo_core::inherents::InherentInternal<#verifier, #inner_types6>>::genesis_transactions();
339+
<#inner_types2 as tuxedo_core::ConstraintChecker>::genesis_transactions();
320340
all_transactions.extend(
321341
transactions
322342
.into_iter()
@@ -329,35 +349,6 @@ pub fn tuxedo_constraint_checker(attrs: TokenStream, body: TokenStream) -> Token
329349
}
330350

331351
}
332-
333-
impl tuxedo_core::ConstraintChecker<#verifier> for #outer_type {
334-
type Error = #error_type;
335-
336-
type InherentHooks = #inherent_hooks;
337-
338-
fn check (
339-
&self,
340-
inputs: &[tuxedo_core::types::Output<#verifier>],
341-
peeks: &[tuxedo_core::types::Output<#verifier>],
342-
outputs: &[tuxedo_core::types::Output<#verifier>],
343-
) -> Result<TransactionPriority, Self::Error> {
344-
match self {
345-
#(
346-
Self::#variants5(inner) => inner.check(inputs, peeks, outputs).map_err(|e| Self::Error::#variants5(e)),
347-
)*
348-
}
349-
}
350-
351-
fn is_inherent(&self) -> bool {
352-
match self {
353-
#(
354-
Self::#variants6(inner) => <#inner_types7 as tuxedo_core::ConstraintChecker<#verifier>>::is_inherent(inner),
355-
)*
356-
}
357-
358-
}
359-
360-
}
361352
};
362353

363354
output.into()

0 commit comments

Comments
 (0)