From a6ddad86b8111c580dea477579091a4b83d286fa Mon Sep 17 00:00:00 2001 From: Rashad Alston Date: Thu, 28 Sep 2023 12:53:27 -0400 Subject: [PATCH] updates --- packages/fuel-indexer-lib/src/manifest.rs | 6 +- packages/fuel-indexer-macros/src/indexer.rs | 80 +++++++++++++------ .../fuel-indexer-test/fuel_indexer_test.yaml | 5 +- .../sway/fuel-predicates/src/main.sw | 8 +- packages/fuel-indexer-types/src/predicate.rs | 40 +++++++--- 5 files changed, 96 insertions(+), 43 deletions(-) diff --git a/packages/fuel-indexer-lib/src/manifest.rs b/packages/fuel-indexer-lib/src/manifest.rs index 3cf94590f..86279618c 100644 --- a/packages/fuel-indexer-lib/src/manifest.rs +++ b/packages/fuel-indexer-lib/src/manifest.rs @@ -103,10 +103,10 @@ pub struct Manifest { resumable: Option, /// Predicates to watch - predicate_templates: Option>, + predicate_templates: Option, /// Predicate ABI - predicate_abi: Option>, + predicate_abi: Option, } impl Manifest { @@ -235,7 +235,7 @@ impl Manifest { } /// Get the indexer predicate ABI. - pub fn predicate_abi(&self) -> Option<&[String]> { + pub fn predicate_abi(&self) -> Option<&str> { self.predicate_abi.as_deref() } diff --git a/packages/fuel-indexer-macros/src/indexer.rs b/packages/fuel-indexer-macros/src/indexer.rs index efa0cd1b1..d780b7b48 100644 --- a/packages/fuel-indexer-macros/src/indexer.rs +++ b/packages/fuel-indexer-macros/src/indexer.rs @@ -20,7 +20,8 @@ use syn::{parse_macro_input, FnArg, Item, ItemMod, PatType, Type}; fn process_fn_items( manifest: &Manifest, - abi_path: Option, + contract_abi_path: Option, + predicate_abi_path: Option, indexer_module: ItemMod, ) -> (proc_macro2::TokenStream, proc_macro2::TokenStream) { if indexer_module.content.is_none() @@ -36,22 +37,23 @@ fn process_fn_items( ) } - let abi = get_json_abi(abi_path).unwrap_or_default(); + let contract_abi = get_json_abi(contract_abi_path).unwrap_or_default(); + let predicate_abi = get_json_abi(predicate_abi_path).unwrap_or_default(); let mut decoded_type_snippets = HashSet::new(); let mut decoded_log_match_arms = HashSet::new(); let mut decoded_type_fields = HashSet::new(); let mut abi_dispatchers = Vec::new(); - let funcs = abi.clone().functions; - let abi_types: Vec = abi + let funcs = contract_abi.clone().functions; + let abi_types: Vec = contract_abi .clone() .types .iter() .map(|t| strip_callpath_from_type_field(t.clone())) .collect(); - let abi_log_types = abi.clone().logged_types.unwrap_or_default(); - let abi_msg_types = abi.clone().messages_types.unwrap_or_default(); + let abi_log_types = contract_abi.clone().logged_types.unwrap_or_default(); + let abi_msg_types = contract_abi.clone().messages_types.unwrap_or_default(); let fuel_types = FUEL_PRIMITIVES .iter() .map(|x| { @@ -388,6 +390,8 @@ fn process_fn_items( }) .collect::>(); + let predicate_configurables = predicate_abi.configurables; + let contents = indexer_module .content .expect("Could not parse input content.") @@ -622,12 +626,39 @@ fn process_fn_items( let data = serialize(&block); decoder.decode_type(ty_id, data); - for tx in block.transactions { + for tx_data in block.transactions { + let tx = tx_data.transaction; + + // TODO: should already have manifest.predicates available for use here + // TODO: should already have access to predicates ABI JSON `configurables` here. + match tx { + fuel::Transaction::Script(fuel::Script { + inputs, + outputs, + witnesses, + .. + }) => { + + let predicates = inputs + .iter() + .zip(witnesses) + .map(|(i, w)| Predicate::try_from((i.to_owned(), w.to_owned()))) + .filter_map(Result::ok) + .collect::>(); + + // if 'restoring' a predicate using the output, then the + // predicate is already saved in the DB. + + // check the the predicate is valid + + }, + _ => {}, + } let mut return_types = Vec::new(); let mut callees = HashSet::new(); - for receipt in tx.receipts { + for receipt in tx_data.receipts { match receipt { fuel::Receipt::Call { id: contract_id, amount, asset_id, gas, param1, to: id, .. } => { #check_if_subscribed_to_contract @@ -924,24 +955,21 @@ pub fn process_indexer_module(attrs: TokenStream, item: TokenStream) -> TokenStr None => proc_macro2::TokenStream::new(), }; - let predicate_abi_tokens = match manifest.predicate_abi() { - Some(abi_paths) => { - let mut result = quote! {}; - for path in abi_paths.iter() { - let tokens = get_abi_tokens( - manifest.namespace(), - path, - manifest.execution_source(), - ProgramType::Predicate, - ); + let (predicate_abi, _) = + prefix_abi_and_schema_paths(manifest.predicate_abi(), manifest.graphql_schema()); - result = quote! { - #result - #tokens - }; - } + let predicate_abi_tokens = match predicate_abi { + Some(ref abi_path) => { + let abi_tokens = get_abi_tokens( + manifest.namespace(), + abi_path, + manifest.execution_source(), + ProgramType::Predicate, + ); - result + quote! { + #abi_tokens + } } None => proc_macro2::TokenStream::new(), }; @@ -957,7 +985,7 @@ pub fn process_indexer_module(attrs: TokenStream, item: TokenStream) -> TokenStr let output = match manifest.execution_source() { ExecutionSource::Native => { let (handler_block, fn_items) = - process_fn_items(&manifest, contract_abi, indexer_module); + process_fn_items(&manifest, contract_abi, predicate_abi, indexer_module); let handler_block = handler_block_native(handler_block); let naitve_main_tokens = native_main(); @@ -978,7 +1006,7 @@ pub fn process_indexer_module(attrs: TokenStream, item: TokenStream) -> TokenStr } ExecutionSource::Wasm => { let (handler_block, fn_items) = - process_fn_items(&manifest, contract_abi, indexer_module); + process_fn_items(&manifest, contract_abi, predicate_abi, indexer_module); let handler_block = handler_block_wasm(handler_block); quote! { diff --git a/packages/fuel-indexer-tests/indexers/fuel-indexer-test/fuel_indexer_test.yaml b/packages/fuel-indexer-tests/indexers/fuel-indexer-test/fuel_indexer_test.yaml index b268141ae..a1103ca21 100644 --- a/packages/fuel-indexer-tests/indexers/fuel-indexer-test/fuel_indexer_test.yaml +++ b/packages/fuel-indexer-tests/indexers/fuel-indexer-test/fuel_indexer_test.yaml @@ -9,4 +9,7 @@ contract_id: identifier: index1 module: wasm: target/wasm32-unknown-unknown/release/fuel_indexer_test.wasm -resumable: true \ No newline at end of file +resumable: true +predicates: + - name: foobar + hash: 00000000000000000000000000000000 \ No newline at end of file diff --git a/packages/fuel-indexer-tests/sway/fuel-predicates/src/main.sw b/packages/fuel-indexer-tests/sway/fuel-predicates/src/main.sw index 30882f319..264a8d055 100644 --- a/packages/fuel-indexer-tests/sway/fuel-predicates/src/main.sw +++ b/packages/fuel-indexer-tests/sway/fuel-predicates/src/main.sw @@ -5,12 +5,12 @@ enum EnumWithGeneric { VariantOne: D, VariantTwo: (), } - + struct StructWithGeneric { field_1: D, field_2: u64, } - + configurable { U8: u8 = 8u8, BOOL: bool = true, @@ -20,12 +20,12 @@ field_2: 16, }, ENUM: EnumWithGeneric = EnumWithGeneric::VariantOne(true), } - + fn main( u_8: u8, switch: bool, some_struct: StructWithGeneric, some_enum: EnumWithGeneric, ) -> bool { - u_8 == U8 && switch == BOOL && some_struct == STRUCT && some_enum == ENUM + u_8 == U8 } diff --git a/packages/fuel-indexer-types/src/predicate.rs b/packages/fuel-indexer-types/src/predicate.rs index 6a0b55e63..2c98c9fc0 100644 --- a/packages/fuel-indexer-types/src/predicate.rs +++ b/packages/fuel-indexer-types/src/predicate.rs @@ -1,6 +1,6 @@ #[allow(unused)] use crate::{ - fuel::{ClientInput, CoinOutput, Script, Transaction, Witness}, + fuel::{ClientInput, CoinOutput, Input, Script, Transaction, Witness}, scalar::{Address, Bytes32, UID}, SizedAsciiString, }; @@ -100,11 +100,18 @@ pub struct Predicate { /// Standardized witness data format witness_data: PredicateWitnessData, + + coin_input: Input, + + coin_output: Option, + + /// Whether or not this predicate is being watched. + watching: bool, } impl Predicate { /// Create a new `Predicate`. - pub fn new(witness_data: Vec) -> Result { + pub fn new(input: Input, witness_data: Vec) -> Result { match PredicateWitnessData::try_from(witness_data) { Ok(witness_data) => { let mut hasher = Sha256::new(); @@ -112,19 +119,33 @@ impl Predicate { let id = UID::new(format!("{:x}", hasher.finalize())) .expect("Failed to create UID."); - Ok(Self { id, witness_data }) + Ok(Self { + id, + witness_data, + coin_output: None, + coin_input: input, + watching: false, + }) } Err(e) => Err(e), } } + + pub fn watch(&mut self) { + self.watching = true; + } + + pub fn unwatch(&mut self) { + self.watching = false; + } } -impl TryFrom for Predicate { +impl TryFrom<(Input, Witness)> for Predicate { type Error = bincode::Error; /// Convert from `Witness` to `Predicate`. - fn try_from(witness: Witness) -> Result { - let witness_data: Vec = witness.into_inner(); - Self::new(witness_data) + fn try_from(data: (Input, Witness)) -> Result { + let witness_data: Vec = data.1.into_inner(); + Self::new(data.0, witness_data) } } @@ -149,9 +170,10 @@ impl From<&Transaction> for Vec { outputs, witnesses, metadata, - }) => witnesses + }) => inputs .iter() - .map(|w| Predicate::try_from(w.to_owned())) + .zip(witnesses) + .map(|(i, w)| Predicate::try_from((i.to_owned(), w.to_owned()))) .filter_map(Result::ok) .collect::>(), _ => unimplemented!(),