@@ -78,6 +78,12 @@ pub enum NtxError {
7878
7979type NtxResult < T > = Result < T , NtxError > ;
8080
81+ /// The result of a successful transaction execution.
82+ ///
83+ /// Contains the transaction ID, any notes that failed during filtering, and note scripts fetched
84+ /// from the remote store that should be persisted to the local DB cache.
85+ pub type NtxExecutionResult = ( TransactionId , Vec < FailedNote > , Vec < ( Word , NoteScript ) > ) ;
86+
8187// NETWORK TRANSACTION CONTEXT
8288// ================================================================================================
8389
@@ -138,8 +144,9 @@ impl NtxContext {
138144 ///
139145 /// # Returns
140146 ///
141- /// On success, returns the [`TransactionId`] of the executed transaction and a list of
142- /// [`FailedNote`]s representing notes that were filtered out before execution.
147+ /// On success, returns an [`NtxExecutionResult`] containing the transaction ID, any notes
148+ /// that failed during filtering, and note scripts fetched from the remote store that should
149+ /// be persisted to the local DB cache.
143150 ///
144151 /// # Errors
145152 ///
@@ -152,7 +159,7 @@ impl NtxContext {
152159 pub fn execute_transaction (
153160 self ,
154161 tx : TransactionCandidate ,
155- ) -> impl FutureMaybeSend < NtxResult < ( TransactionId , Vec < FailedNote > ) > > {
162+ ) -> impl FutureMaybeSend < NtxResult < NtxExecutionResult > > {
156163 let TransactionCandidate {
157164 account,
158165 notes,
@@ -185,6 +192,9 @@ impl NtxContext {
185192 // Execute transaction.
186193 let executed_tx = Box :: pin ( self . execute ( & data_store, successful_notes) ) . await ?;
187194
195+ // Collect scripts fetched from the remote store during execution.
196+ let scripts_to_cache = data_store. take_fetched_scripts ( ) . await ;
197+
188198 // Prove transaction.
189199 let tx_inputs: TransactionInputs = executed_tx. into ( ) ;
190200 let proven_tx = Box :: pin ( self . prove ( & tx_inputs) ) . await ?;
@@ -195,7 +205,7 @@ impl NtxContext {
195205 // Submit transaction to block producer.
196206 self . submit ( & proven_tx) . await ?;
197207
198- Ok ( ( proven_tx. id ( ) , failed_notes) )
208+ Ok ( ( proven_tx. id ( ) , failed_notes, scripts_to_cache ) )
199209 } )
200210 . in_current_span ( )
201211 . await
@@ -341,8 +351,11 @@ struct NtxDataStore {
341351 store : StoreClient ,
342352 /// LRU cache for storing retrieved note scripts to avoid repeated store calls.
343353 script_cache : LruCache < Word , NoteScript > ,
344- /// Local database for persistent note script caching .
354+ /// Local database for persistent note script.
345355 db : Db ,
356+ /// Scripts fetched from the remote store during execution, to be persisted by the
357+ /// coordinator.
358+ fetched_scripts : Arc < Mutex < Vec < ( Word , NoteScript ) > > > ,
346359 /// Mapping of storage map roots to storage slot names observed during various calls.
347360 ///
348361 /// The registered slot names are subsequently used to retrieve storage map witnesses from the
@@ -388,10 +401,16 @@ impl NtxDataStore {
388401 store,
389402 script_cache,
390403 db,
404+ fetched_scripts : Arc :: new ( Mutex :: new ( Vec :: new ( ) ) ) ,
391405 storage_slots : Arc :: new ( Mutex :: new ( BTreeMap :: default ( ) ) ) ,
392406 }
393407 }
394408
409+ /// Returns the list of note scripts fetched from the remote store during execution.
410+ async fn take_fetched_scripts ( & self ) -> Vec < ( Word , NoteScript ) > {
411+ self . fetched_scripts . lock ( ) . await . drain ( ..) . collect ( )
412+ }
413+
395414 /// Registers storage map slot names for the given account ID and storage header.
396415 ///
397416 /// These slot names are subsequently used to query for storage map witnesses against the store.
@@ -550,8 +569,8 @@ impl DataStore for NtxDataStore {
550569 } ) ?;
551570
552571 if let Some ( script) = maybe_script {
553- // Best-effort persist — don't fail the transaction if DB write fails .
554- let _ = self . db . insert_note_script ( script_root, & script) . await ;
572+ // Collect for later persistence by the coordinator .
573+ self . fetched_scripts . lock ( ) . await . push ( ( script_root, script. clone ( ) ) ) ;
555574 self . script_cache . put ( script_root, script. clone ( ) ) . await ;
556575 Ok ( Some ( script) )
557576 } else {
0 commit comments