mirror of
https://github.com/jwinterm/grin-wallet.git
synced 2026-10-19 16:18:46 +02:00
Contracts: only create a context on a genuine miss
get_private_context() flattened "missing context" and real store/keychain errors into one error, so the contract code created a fresh context on ANY error (e.g. a decryption failure from a wrong keychain mask), masking the real problem. - add Error::NotFoundErr; the grin_store conversion maps NotFoundErr through faithfully (other store errors stay Backend). - contract get_or_create / get_net_change / sign create-or-skip only on NotFoundErr and propagate every other error. Addresses PR #754 review (context.rs, utils.rs, sign.rs).
This commit is contained in:
@@ -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())
|
||||
})?;
|
||||
|
||||
@@ -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)?;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
+10
-1
@@ -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<grin_store::Error> 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)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user