@@ -809,26 +809,35 @@ pub trait BlockStorage<N: Network>: 'static + Clone + Send + Sync {
809809 Ok ( solutions. into_owned ( ) )
810810 }
811811
812- /// Returns the prover solution for the given solution ID.
813- fn get_solution ( & self , solution_id : & SolutionID < N > ) -> Result < Solution < N > > {
812+ /// Returns the prover solution for the given solution ID, or `None` if no reference to this solution
813+ /// exists in the ledger.
814+ fn get_solution ( & self , solution_id : & SolutionID < N > ) -> Result < Option < Solution < N > > > {
814815 // Retrieve the block height for the solution ID.
815816 let Some ( block_height) = self . find_block_height_from_solution_id ( solution_id) ? else {
816- bail ! ( "The block height for solution ID '{solution_id}' is missing in block storage" )
817+ // In this case, the solution is not yet known to the ledger.
818+ return Ok ( None ) ;
817819 } ;
818- // Retrieve the block hash.
820+
821+ // Errors below are more severe, as it measn there is a reference to solution, but
822+ // the solution itself is missing.
823+
824+ // Get the block hash for the given height.
819825 let Some ( block_hash) = self . get_block_hash ( block_height) ? else {
820826 bail ! ( "The block hash for block '{block_height}' is missing in block storage" )
821827 } ;
822- // Retrieve the solutions.
828+
829+ // Get the solutions for the block.
823830 let Some ( solutions) = self . solutions_map ( ) . get_confirmed ( & block_hash) ? else {
824831 bail ! ( "The solutions for block '{block_height}' are missing in block storage" )
825832 } ;
833+
826834 // Retrieve the prover solution.
827- match solutions. deref ( ) . deref ( ) {
828- Some ( solutions) => solutions. get ( solution_id) . cloned ( ) . ok_or_else ( || {
829- anyhow ! ( "The prover solution for solution ID '{solution_id}' is missing in block storage" )
830- } ) ,
831- _ => bail ! ( "The prover solution for solution ID '{solution_id}' is missing in block storage" ) ,
835+ if let Some ( solutions) = solutions. deref ( ) . deref ( )
836+ && let Some ( solution) = solutions. get ( solution_id) . cloned ( )
837+ {
838+ Ok ( Some ( solution) )
839+ } else {
840+ bail ! ( "The prover solution for solution ID '{solution_id}' is missing in block storage" ) ;
832841 }
833842 }
834843
@@ -846,7 +855,7 @@ pub trait BlockStorage<N: Network>: 'static + Clone + Send + Sync {
846855 // Retrieve the transactions.
847856 transaction_ids
848857 . iter ( )
849- . map ( |transaction_id| self . get_confirmed_transaction ( * transaction_id) )
858+ . map ( |transaction_id| self . get_confirmed_transaction ( transaction_id) )
850859 . collect :: < Result < Option < Transactions < _ > > > > ( )
851860 }
852861
@@ -855,7 +864,7 @@ pub trait BlockStorage<N: Network>: 'static + Clone + Send + Sync {
855864 Ok ( self . aborted_transaction_ids_map ( ) . get_confirmed ( block_hash) ?. map ( |x| x. into_owned ( ) ) )
856865 }
857866
858- /// Returns the transaction for the given `TransactionID`.
867+ /// Returns the transaction for the given `TransactionID`, or `None` if no transaction of this ID exists .
859868 fn get_transaction ( & self , transaction_id : & N :: TransactionID ) -> Result < Option < Transaction < N > > > {
860869 // Check if the transaction was rejected or aborted.
861870 // Note: We can only retrieve accepted or rejected transactions. We cannot retrieve aborted transactions.
@@ -868,37 +877,45 @@ pub trait BlockStorage<N: Network>: 'static + Clone + Send + Sync {
868877
869878 let Some ( confirmed) = transactions. find_confirmed_transaction_for_unconfirmed_transaction_id ( transaction_id)
870879 else {
871- if let Some ( aborted_ids) = self . get_block_aborted_transaction_ids ( & block_hash) ? {
872- if aborted_ids. contains ( transaction_id) {
873- bail ! ( "Transaction '{transaction_id}' was aborted in block '{block_hash}'" ) ;
874- }
880+ if let Some ( aborted_ids) = self . get_block_aborted_transaction_ids ( & block_hash) ?
881+ && aborted_ids. contains ( transaction_id)
882+ {
883+ bail ! ( "Transaction '{transaction_id}' was aborted in block '{block_hash}'" ) ;
884+ } else {
885+ return Ok ( None ) ;
875886 }
876- bail ! ( "Missing transaction '{transaction_id}' in block storage" ) ;
877887 } ;
878888 Ok ( Some ( confirmed. transaction ( ) . clone ( ) ) )
879889 }
880890
881- /// Returns the confirmed transaction for the given `transaction ID`.
882- fn get_confirmed_transaction ( & self , transaction_id : N :: TransactionID ) -> Result < Option < ConfirmedTransaction < N > > > {
891+ /// Returns the confirmed transaction for the given `transaction ID`, or `None` if no confirmed transaction of this ID exists .
892+ fn get_confirmed_transaction ( & self , transaction_id : & N :: TransactionID ) -> Result < Option < ConfirmedTransaction < N > > > {
883893 // Retrieve the transaction.
884- let Some ( transaction) = self . get_transaction ( & transaction_id) ? else {
885- bail ! ( "Missing transaction '{transaction_id}' in block storage" ) ;
894+ let Some ( transaction) = self . get_transaction ( transaction_id) ? else {
895+ return Ok ( None ) ;
886896 } ;
897+
887898 // Retrieve the confirmed attributes.
888899 let Some ( ( _, confirmed_type, finalize_operations) ) =
889900 self . confirmed_transactions_map ( ) . get_confirmed ( & transaction. id ( ) ) ?. map ( |x| x. into_owned ( ) )
890901 else {
891- bail ! ( "Missing confirmed transaction '{transaction_id}' in block storage" )
902+ return Ok ( None ) ;
892903 } ;
904+
893905 // Construct the confirmed transaction.
894906 to_confirmed_transaction ( confirmed_type, transaction, finalize_operations) . map ( Some )
895907 }
896908
897- /// Get the unconfirmed transaction for the given `TransactionID` .
909+ /// Retrieve an unconfirmed transaction using its ID .
898910 ///
899911 /// For unconfirmed and accepted transactions, this will return original transaction issued by the client.
900912 /// This function also returns the original execution/deployment for a rejected transaction,
901913 /// even when the given `TransactionID` is of a fee transaction.
914+ ///
915+ /// # Returns
916+ /// - `Ok(txn)` if the transaction exists and is not confirmed
917+ /// - `Ok(None)` if no such unconfirmed transaction exist
918+ /// - `Err(_)` if any other error occured (most likely a storage corruption)
902919 fn get_unconfirmed_transaction ( & self , transaction_id : & N :: TransactionID ) -> Result < Option < Transaction < N > > > {
903920 // Check if the transaction was rejected or aborted.
904921 // Note: We can only retrieve accepted or rejected transactions. We cannot retrieve aborted transactions.
@@ -907,10 +924,13 @@ pub trait BlockStorage<N: Network>: 'static + Clone + Send + Sync {
907924 Some ( transactions) => {
908925 match transactions. find_confirmed_transaction_for_unconfirmed_transaction_id ( transaction_id) {
909926 Some ( confirmed) => Ok ( Some ( confirmed. to_unconfirmed_transaction ( ) ?) ) ,
910- None => bail ! ( "Missing transaction '{transaction_id}' in block storage" ) ,
927+ None => Ok ( None ) ,
911928 }
912929 }
913- None => bail ! ( "Missing transactions for block '{block_hash}' in block storage" ) ,
930+ // This is an error, because there must always be a transactions entry for a known block hash.
931+ None => bail ! (
932+ "Transaction '{transaction_id}' is associated with a block '{block_hash}', but no transactions entry exists for it"
933+ ) ,
914934 } ,
915935 None => {
916936 let Some ( txn) = self . transaction_store ( ) . get_transaction ( transaction_id) ? else {
@@ -921,12 +941,15 @@ pub trait BlockStorage<N: Network>: 'static + Clone + Send + Sync {
921941 if let Transaction :: Fee ( _, fee) = txn {
922942 // Look up the original transaction in its block.
923943 let Some ( block_hash) = self . find_block_hash ( transaction_id) ? else {
924- bail ! ( "Missing fee transaction '{transaction_id}' in block storage" ) ;
944+ // This is an error, because a fee transaction must always have an original transaction associated with it.
945+ bail ! ( "Transaction {transaction_id} is a fee transaction with no associated block" ) ;
925946 } ;
926947
927948 match self . get_block_transactions ( & block_hash) ? {
928949 Some ( transactions) => transactions. find_unconfirmed_transaction_for_transition_id ( fee. id ( ) ) ,
929- None => bail ! ( "Missing transactions for block '{block_hash}' in block storage" ) ,
950+ None => bail ! (
951+ "Transaction {transaction_id} is associated with block '{block_hash}' but no transacitons entry exists for it"
952+ ) ,
930953 }
931954 } else {
932955 Ok ( Some ( txn) )
@@ -1365,7 +1388,7 @@ impl<N: Network, B: BlockStorage<N>> BlockStore<N, B> {
13651388 }
13661389
13671390 /// Returns the prover solution for the given solution ID.
1368- pub fn get_solution ( & self , solution_id : & SolutionID < N > ) -> Result < Solution < N > > {
1391+ pub fn get_solution ( & self , solution_id : & SolutionID < N > ) -> Result < Option < Solution < N > > > {
13691392 self . storage . get_solution ( solution_id)
13701393 }
13711394
@@ -1382,24 +1405,41 @@ impl<N: Network, B: BlockStorage<N>> BlockStore<N, B> {
13821405 self . storage . get_block_aborted_transaction_ids ( block_hash)
13831406 }
13841407
1385- /// Returns the transaction for the given `transaction ID` .
1408+ /// Retrieve a transaction using its ID .
13861409 ///
13871410 /// For a rejected transaction, this returns the fee transaction, not the original/unconfirmed one.
1411+ ///
1412+ /// # Returns
1413+ /// - `Ok(txn)` if the transaction exists
1414+ /// - `Ok(None)` if no such transaction exist
1415+ /// - `Err(_)` if any other error occured
1416+ ///
13881417 pub fn get_transaction ( & self , transaction_id : & N :: TransactionID ) -> Result < Option < Transaction < N > > > {
13891418 self . storage . get_transaction ( transaction_id)
13901419 }
13911420
1392- /// Returns the confirmed transaction for the given `transaction ID`.
1421+ /// Retreive a confirmed transation using its ID.
1422+ ///
1423+ /// # Returns
1424+ /// - `Ok(txn)` if the transaction exists
1425+ /// - `Ok(None)` if no such confirmed transaction exist
1426+ /// - `Err(_)` if no such transaction exist or any other error occured
13931427 pub fn get_confirmed_transaction (
13941428 & self ,
13951429 transaction_id : & N :: TransactionID ,
13961430 ) -> Result < Option < ConfirmedTransaction < N > > > {
1397- self . storage . get_confirmed_transaction ( * transaction_id)
1431+ self . storage . get_confirmed_transaction ( transaction_id)
13981432 }
13991433
1400- /// Returns the unconfirmed transaction for the given `transaction ID` .
1401- ///
1434+ /// Retrieve an unconfirmed transaction using its ID .
1435+ ///
14021436 /// For a rejected transaction, this returns the origin transaction issued by the user, not the fee transaction.
1437+ ///
1438+ /// # Returns
1439+ /// - `Ok(txn)` if the transaction exists and is not confirmed
1440+ /// - `Ok(None)` if no such unconfirmed transaction exist
1441+ /// - `Err(_)` if any other error occured
1442+ ///
14031443 pub fn get_unconfirmed_transaction ( & self , transaction_id : & N :: TransactionID ) -> Result < Option < Transaction < N > > > {
14041444 self . storage . get_unconfirmed_transaction ( transaction_id)
14051445 }
0 commit comments