Fix race conditions with proof state updates.

Add a strict set of updates to prevent incorrect state changes and correct
usage. Supporting the transaction at the trait level prevented some cases, but
having a strict set of state change flows is better.

This bug was found while developing the signatory. The keys are read from
memory, triggering race conditions at the database, and some `Pending` states
are selected (instead of just selecting `Unspent`).

This PR also introduces a set of generic database tests to be executed for all
database implementations, this test suite will make sure writing and
maintaining new database drivers
This commit is contained in:
Cesar Rodas
2025-04-19 02:45:33 -03:00
parent 3626dd2f6a
commit abdde307c6
12 changed files with 188 additions and 19 deletions

View File

@@ -1,7 +1,7 @@
//! CDK Database
#[cfg(feature = "mint")]
mod mint;
pub mod mint;
#[cfg(feature = "wallet")]
mod wallet;
@@ -16,6 +16,8 @@ pub use mint::{
#[cfg(feature = "wallet")]
pub use wallet::Database as WalletDatabase;
use crate::state;
/// CDK_database error
#[derive(Debug, thiserror::Error)]
pub enum Error {
@@ -53,4 +55,16 @@ pub enum Error {
/// Invalid keyset
#[error("Unknown or invalid keyset")]
InvalidKeysetId,
/// Invalid state transition
#[error("Invalid state transition")]
InvalidStateTransition(state::Error),
}
impl From<state::Error> for Error {
fn from(state: state::Error) -> Self {
match state {
state::Error::AlreadySpent => Error::AttemptUpdateSpentProof,
_ => Error::InvalidStateTransition(state),
}
}
}