diff --git a/impls/src/backends/lmdb.rs b/impls/src/backends/lmdb.rs index c0c4164..335eb8e 100644 --- a/impls/src/backends/lmdb.rs +++ b/impls/src/backends/lmdb.rs @@ -377,6 +377,8 @@ where let (blind_xor_key, nonce_xor_key) = private_ctx_xor_keys(&self.keychain(keychain_mask)?, slate_id)?; + // A missing context surfaces as Error::NotFoundErr (via the grin_store + // conversion), letting callers distinguish it from other store errors. let mut ctx: Context = option_to_not_found(self.db.get_ser(&ctx_key, None), || { format!("Slate id: {:x?}", slate_id.to_vec()) })?; diff --git a/libwallet/src/contract/actions/sign.rs b/libwallet/src/contract/actions/sign.rs index aef428a..544da7f 100644 --- a/libwallet/src/contract/actions/sign.rs +++ b/libwallet/src/contract/actions/sign.rs @@ -35,10 +35,12 @@ where C: NodeClient + 'a, K: Keychain + 'a, { - // Compute if we will add outputs at this step + // Compute if we will add outputs at this step. Only a missing context means we + // still need to add them; propagate any other error. let will_add_outputs = match w.get_private_context(keychain_mask, slate.id.as_bytes()) { Ok(ctx) => ctx.get_inputs().len() + ctx.get_outputs().len() == 0, - Err(_) => true, + Err(Error::NotFoundErr(_)) => true, + Err(e) => return Err(e), }; // Compute state for 'sign' let (sl, mut context) = compute(w, keychain_mask, slate, setup_args)?; diff --git a/libwallet/src/contract/context.rs b/libwallet/src/contract/context.rs index a260f22..15a5489 100644 --- a/libwallet/src/contract/context.rs +++ b/libwallet/src/contract/context.rs @@ -41,7 +41,8 @@ where let maybe_context = w.get_private_context(keychain_mask, slate.id.as_bytes()); let context = match maybe_context { - Err(_) => { + // Only create a new context when there genuinely isn't one; propagate other errors. + Err(Error::NotFoundErr(_)) => { // Get data required for creating a context let height = w.w2n_client().get_chain_tip()?.0; let parent_key_id = @@ -57,6 +58,7 @@ where false, )? } + Err(e) => return Err(e), Ok(ctx) => ctx, }; Ok(context) diff --git a/libwallet/src/contract/utils.rs b/libwallet/src/contract/utils.rs index 02550af..73846e1 100644 --- a/libwallet/src/contract/utils.rs +++ b/libwallet/src/contract/utils.rs @@ -158,7 +158,10 @@ where } expected_net_change = Some(ctx.get_net_change()); } - Err(_) => debug!("contract::utils::get_net_change => context not found"), + Err(Error::NotFoundErr(_)) => { + debug!("contract::utils::get_net_change => context not found") + } + Err(e) => return Err(e), }; // Fail if net_change was not passed to setup_args and was also not present in the context. diff --git a/libwallet/src/error.rs b/libwallet/src/error.rs index 7335330..ee64d47 100644 --- a/libwallet/src/error.rs +++ b/libwallet/src/error.rs @@ -81,6 +81,10 @@ pub enum Error { #[error("Wallet store error: {0}")] Backend(String), + /// Requested item was not found in the wallet store + #[error("Not found: {0}")] + NotFoundErr(String), + /// Callback implementation error conversion #[error("Restore Error")] Restore, @@ -348,7 +352,12 @@ pub enum Error { impl From for Error { fn from(error: grin_store::Error) -> Error { - Error::Backend(format!("{}", error)) + // Preserve "not found" so callers can distinguish a missing item from other + // store errors; everything else collapses to a generic backend error. + match error { + grin_store::Error::NotFoundErr(s) => Error::NotFoundErr(s), + other => Error::Backend(format!("{}", other)), + } } }