Skip to content

Commit

Permalink
Annotate transactions with original hash identities
Browse files Browse the repository at this point in the history
  • Loading branch information
Joshy Orndorff committed Oct 10, 2023
1 parent d1afb63 commit ca8fdbe
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 32 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 22 additions & 16 deletions tuxedo-core/aggregator/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,28 +171,34 @@ pub fn tuxedo_constraint_checker(attrs: TokenStream, body: TokenStream) -> Token

fn create_inherents(
authoring_inherent_data: &InherentData,
previous_inherents: Vec<tuxedo_core::types::Transaction<#verifier, #outer_type>>,
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| {
match tx.checker {
#outer_type::#variants3(ref inner_checker) => Some(
tuxedo_core::types::Transaction {
inputs: tx.inputs.clone(),
peeks: tx.peeks.clone(),
outputs: tx.outputs.clone(),
checker: inner_checker.clone(),
}
),
_ => None,
}
})
.collect();
let previous_inherents = previous_inherents
.iter()
.filter_map(|(tx, hash)| {
match tx.checker {
#outer_type::#variants3(ref inner_checker) => Some(
(
tuxedo_core::types::Transaction {
inputs: tx.inputs.clone(),
peeks: tx.peeks.clone(),
outputs: tx.outputs.clone(),
checker: inner_checker.clone(),
},
*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>())
Expand Down Expand Up @@ -274,7 +280,7 @@ pub fn tuxedo_constraint_checker(attrs: TokenStream, body: TokenStream) -> Token
Self::#variants6(inner) => <#inner_types6 as tuxedo_core::ConstraintChecker<#verifier>>::is_inherent(inner),
)*
}

}

}
Expand Down
12 changes: 10 additions & 2 deletions tuxedo-core/src/executive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use log::debug;
use parity_scale_codec::{Decode, Encode};
use scale_info::TypeInfo;
use sp_api::{BlockT, HashT, HeaderT, TransactionValidity};
use sp_core::H256;
use sp_inherents::{CheckInherentsResult, InherentData};
use sp_runtime::{
traits::BlakeTwo256,
Expand Down Expand Up @@ -423,13 +424,20 @@ impl<
);

// Extract the beginning-of-block inherents from the previous block.
// The parent is already imported, so we know it is valid and we know its inherents came first
// The parent is already imported, so we know it is valid and we know its inherents came first.
// We also annotate each transaction with its original hash for purposes of constructing output refs later.
// This is necessary because the transaction hash changes as we unwrap layers of aggregation,
// and we need an original universal transaction id.
// TODO Enforce that inherents are first in the execution path by making sure there are no more inherents after the first non-inherent.
let previous_blocks_inherents: Vec<<B as BlockT>::Extrinsic> = parent
let previous_blocks_inherents: Vec<(<B as BlockT>::Extrinsic, H256)> = parent
.extrinsics()
.iter()
.cloned()
.take_while(|tx| tx.checker.is_inherent())
.map(|tx| {
let id = BlakeTwo256::hash_of(&tx.encode());
(tx, id)
})
.collect();

log::info!(
Expand Down
12 changes: 8 additions & 4 deletions tuxedo-core/src/inherents.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
use parity_scale_codec::{Decode, Encode};
use scale_info::TypeInfo;
use sp_core::H256;
use sp_inherents::{
CheckInherentsResult, InherentData, InherentIdentifier, IsFatalError, MakeFatalError,
};
Expand Down Expand Up @@ -112,7 +113,7 @@ pub trait TuxedoInherent<V: Verifier, C: ConstraintChecker<V>>: Sized + TypeInfo
// The option represents the so-called "first block hack".
// We need a way to initialize the chain with a first inherent on block one
// where there is no previous inherent. Once we introduce genesis extrinsics, this can be removed.
previous_inherent: Option<Transaction<V, C>>,
previous_inherent: Option<(Transaction<V, C>, H256)>,
) -> Transaction<V, C>;

/// Perform off-chain pre-execution checks on the inherents.
Expand All @@ -139,7 +140,7 @@ pub trait InherentInternal<V: Verifier, C: ConstraintChecker<V>>: Sized + TypeIn
/// The inherent data is supplied by the authoring node.
fn create_inherents(
authoring_inherent_data: &InherentData,
previous_inherents: Vec<Transaction<V, C>>,
previous_inherents: Vec<(Transaction<V, C>, H256)>,
) -> Vec<Transaction<V, C>>;

/// Perform off-chain pre-execution checks on the inherents.
Expand All @@ -165,7 +166,7 @@ impl<V: Verifier, C: ConstraintChecker<V>, T: TuxedoInherent<V, C> + 'static> In

fn create_inherents(
authoring_inherent_data: &InherentData,
previous_inherents: Vec<Transaction<V, C>>,
previous_inherents: Vec<(Transaction<V, C>, H256)>,
) -> Vec<Transaction<V, C>> {
if previous_inherents.len() > 1 {
panic!("Authoring a leaf inherent constraint checker, but multiple previous inherents were supplied.")
Expand Down Expand Up @@ -220,7 +221,10 @@ impl<V: Verifier, C: ConstraintChecker<V>, T: TuxedoInherent<V, C> + 'static> In
impl<V: Verifier, C: ConstraintChecker<V>> InherentInternal<V, C> for () {
type Error = MakeFatalError<()>;

fn create_inherents(_: &InherentData, _: Vec<Transaction<V, C>>) -> Vec<Transaction<V, C>> {
fn create_inherents(
_: &InherentData,
_: Vec<(Transaction<V, C>, H256)>,
) -> Vec<Transaction<V, C>> {
Vec::new()
}

Expand Down
2 changes: 2 additions & 0 deletions wardrobe/timestamp/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ sp-inherents = { default_features = false, workspace = true }
sp-runtime = { default_features = false, workspace = true }
sp-std = { default_features = false, workspace = true }
sp-timestamp = { default_features = false, workspace = true }
sp-core = { default_features = false, workspace = true }
tuxedo-core = { default-features = false, path = "../../tuxedo-core" }

[features]
Expand All @@ -27,6 +28,7 @@ std = [
"sp-inherents/std",
"sp-runtime/std",
"sp-std/std",
"sp-core/std",
"sp-timestamp/std",
"serde",
]
19 changes: 9 additions & 10 deletions wardrobe/timestamp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use parity_scale_codec::{Decode, Encode};
use scale_info::TypeInfo;
#[cfg(feature = "std")]
use serde::{Deserialize, Serialize};
use sp_core::H256;
use sp_inherents::{CheckInherentsResult, InherentData};
use sp_runtime::{traits::BlakeTwo256, transaction_validity::TransactionPriority};
use sp_std::{vec, vec::Vec};
Expand All @@ -27,7 +28,8 @@ use tuxedo_core::{
inherents::{TuxedoInherent, TuxedoInherentAdapter},
support_macros::{CloneNoBound, DebugNoBound, DefaultNoBound},
types::{Input, Output, Transaction},
verifier::UpForGrabs, SimpleConstraintChecker, Verifier,
verifier::UpForGrabs,
SimpleConstraintChecker, Verifier,
};

#[cfg(test)]
Expand Down Expand Up @@ -271,19 +273,17 @@ impl<T: TimestampConfig + 'static, V: Verifier + From<UpForGrabs>> SimpleConstra
fn is_inherent(&self) -> bool {
true
}


}

impl<V: Verifier + From<UpForGrabs>, T: TimestampConfig + 'static>
TuxedoInherent<V, Self> for SetTimestamp<T>
impl<V: Verifier + From<UpForGrabs>, T: TimestampConfig + 'static> TuxedoInherent<V, Self>
for SetTimestamp<T>
{
type Error = sp_timestamp::InherentError;
const INHERENT_IDENTIFIER: sp_inherents::InherentIdentifier = sp_timestamp::INHERENT_IDENTIFIER;

fn create_inherent(
authoring_inherent_data: &InherentData,
previous_inherent: Option<Transaction<V, Self>>,
previous_inherent: Option<(Transaction<V, Self>, H256)>,
) -> tuxedo_core::types::Transaction<V, Self> {
// Extract the current timestamp from the inherent data
let timestamp_millis: u64 = authoring_inherent_data
Expand All @@ -308,7 +308,7 @@ impl<V: Verifier + From<UpForGrabs>, T: TimestampConfig + 'static>
// We don't need any inputs, so just do nothing.
}
(None, _) => panic!("Attemping to construct timestamp inherent with no previous inherent (and not block 1)."),
(Some(previous_inherent), _) => {
(Some((previous_inherent, previous_id)), _) => {
// This is the the normal case. We create a full previous input to consume.
let prev_best_index = previous_inherent
.outputs
Expand All @@ -320,9 +320,8 @@ impl<V: Verifier + From<UpForGrabs>, T: TimestampConfig + 'static>
.try_into()
.expect("There should not be more than u32::max_value outputs in a transaction.");

// TODO should we have some generic way to refer to the hashing algo?
let output_ref = OutputRef {
tx_hash: BlakeTwo256::hash_of(&previous_inherent.encode()),
tx_hash: previous_id,
index: prev_best_index,
};

Expand All @@ -333,7 +332,7 @@ impl<V: Verifier + From<UpForGrabs>, T: TimestampConfig + 'static>
// Once this is fixed more properly (like by using evictions)
// I should be able to not mention UpForGrabs here at all.
redeemer: Vec::new(),
};
};

inputs.push(input);
}
Expand Down

0 comments on commit ca8fdbe

Please sign in to comment.