|
@@ -111,10 +111,13 @@ pub trait Batch<'a> {
|
|
|
|
|
|
#[async_trait::async_trait]
|
|
#[async_trait::async_trait]
|
|
/// Main storage layer
|
|
/// Main storage layer
|
|
-pub trait Storage<'a, B>
|
|
|
|
-where
|
|
|
|
- B: Batch<'a>,
|
|
|
|
-{
|
|
|
|
|
|
+pub trait Storage<'a> {
|
|
|
|
+ /// The batch trait.
|
|
|
|
+ ///
|
|
|
|
+ /// This batch is needed to perform the changes in the transactions and
|
|
|
|
+ /// payments in a atomic way
|
|
|
|
+ type Batch: Batch<'a>;
|
|
|
|
+
|
|
/// Begins a transaction
|
|
/// Begins a transaction
|
|
///
|
|
///
|
|
/// A transaction prepares the storage for a batch of operations, where all
|
|
/// A transaction prepares the storage for a batch of operations, where all
|
|
@@ -124,7 +127,7 @@ where
|
|
/// the changes in the transactions and payments.
|
|
/// the changes in the transactions and payments.
|
|
///
|
|
///
|
|
/// The batch has also a rollback
|
|
/// The batch has also a rollback
|
|
- async fn begin(&'a self) -> Result<B, Error>;
|
|
|
|
|
|
+ async fn begin(&'a self) -> Result<Self::Batch, Error>;
|
|
|
|
|
|
/// Returns a payment object by ID.
|
|
/// Returns a payment object by ID.
|
|
async fn get_payment(&self, id: &PaymentId) -> Result<Payment, Error>;
|
|
async fn get_payment(&self, id: &PaymentId) -> Result<Payment, Error>;
|
|
@@ -135,7 +138,6 @@ where
|
|
if payment.is_spendable() {
|
|
if payment.is_spendable() {
|
|
Ok(payment)
|
|
Ok(payment)
|
|
} else {
|
|
} else {
|
|
- println!("{:?}", payment);
|
|
|
|
Err(Error::NotFound)
|
|
Err(Error::NotFound)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -218,10 +220,9 @@ pub mod test {
|
|
};
|
|
};
|
|
}
|
|
}
|
|
|
|
|
|
- pub async fn transaction<'a, T, B>(storage: &'a T, assets: AssetManager)
|
|
|
|
|
|
+ pub async fn transaction<'a, T>(storage: &'a T, assets: AssetManager)
|
|
where
|
|
where
|
|
- T: Storage<'a, B>,
|
|
|
|
- B: Batch<'a>,
|
|
|
|
|
|
+ T: Storage<'a>,
|
|
{
|
|
{
|
|
let deposit = Transaction::new_external_deposit(
|
|
let deposit = Transaction::new_external_deposit(
|
|
"test reference".to_owned(),
|
|
"test reference".to_owned(),
|
|
@@ -245,12 +246,9 @@ pub mod test {
|
|
assert!(storage.get_transaction(&deposit.id()).await.is_ok());
|
|
assert!(storage.get_transaction(&deposit.id()).await.is_ok());
|
|
}
|
|
}
|
|
|
|
|
|
- pub async fn transaction_not_available_until_commit<'a, T, B>(
|
|
|
|
- storage: &'a T,
|
|
|
|
- assets: AssetManager,
|
|
|
|
- ) where
|
|
|
|
- T: Storage<'a, B>,
|
|
|
|
- B: Batch<'a>,
|
|
|
|
|
|
+ pub async fn transaction_not_available_until_commit<'a, T>(storage: &'a T, assets: AssetManager)
|
|
|
|
+ where
|
|
|
|
+ T: Storage<'a>,
|
|
{
|
|
{
|
|
let deposit = Transaction::new_external_deposit(
|
|
let deposit = Transaction::new_external_deposit(
|
|
"test reference".to_owned(),
|
|
"test reference".to_owned(),
|
|
@@ -275,10 +273,9 @@ pub mod test {
|
|
assert!(storage.get_transaction(&deposit.id()).await.is_ok());
|
|
assert!(storage.get_transaction(&deposit.id()).await.is_ok());
|
|
}
|
|
}
|
|
|
|
|
|
- pub async fn does_not_update_spent_payments<'a, T, B>(storage: &'a T, assets: AssetManager)
|
|
|
|
|
|
+ pub async fn does_not_update_spent_payments<'a, T>(storage: &'a T, assets: AssetManager)
|
|
where
|
|
where
|
|
- T: Storage<'a, B>,
|
|
|
|
- B: Batch<'a>,
|
|
|
|
|
|
+ T: Storage<'a>,
|
|
{
|
|
{
|
|
let mut writer = storage.begin().await.expect("writer");
|
|
let mut writer = storage.begin().await.expect("writer");
|
|
let mut rng = rand::thread_rng();
|
|
let mut rng = rand::thread_rng();
|
|
@@ -334,50 +331,41 @@ pub mod test {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- pub async fn pending_new_payments_are_not_spendable<'a, T, B>(
|
|
|
|
- storage: &'a T,
|
|
|
|
- assets: AssetManager,
|
|
|
|
- ) where
|
|
|
|
- T: Storage<'a, B>,
|
|
|
|
- B: Batch<'a>,
|
|
|
|
|
|
+ pub async fn pending_new_payments_are_not_spendable<'a, T>(storage: &'a T, assets: AssetManager)
|
|
|
|
+ where
|
|
|
|
+ T: Storage<'a>,
|
|
{
|
|
{
|
|
not_spendable_new_payments_not_spendable(storage, assets, Status::Pending).await
|
|
not_spendable_new_payments_not_spendable(storage, assets, Status::Pending).await
|
|
}
|
|
}
|
|
|
|
|
|
- pub async fn processing_new_payments_are_not_spendable<'a, T, B>(
|
|
|
|
|
|
+ pub async fn processing_new_payments_are_not_spendable<'a, T>(
|
|
storage: &'a T,
|
|
storage: &'a T,
|
|
assets: AssetManager,
|
|
assets: AssetManager,
|
|
) where
|
|
) where
|
|
- T: Storage<'a, B>,
|
|
|
|
- B: Batch<'a>,
|
|
|
|
|
|
+ T: Storage<'a>,
|
|
{
|
|
{
|
|
not_spendable_new_payments_not_spendable(storage, assets, Status::Processing).await
|
|
not_spendable_new_payments_not_spendable(storage, assets, Status::Processing).await
|
|
}
|
|
}
|
|
|
|
|
|
- pub async fn cancelled_new_payments_are_not_spendable<'a, T, B>(
|
|
|
|
|
|
+ pub async fn cancelled_new_payments_are_not_spendable<'a, T>(
|
|
storage: &'a T,
|
|
storage: &'a T,
|
|
assets: AssetManager,
|
|
assets: AssetManager,
|
|
) where
|
|
) where
|
|
- T: Storage<'a, B>,
|
|
|
|
- B: Batch<'a>,
|
|
|
|
|
|
+ T: Storage<'a>,
|
|
{
|
|
{
|
|
not_spendable_new_payments_not_spendable(storage, assets, Status::Cancelled).await
|
|
not_spendable_new_payments_not_spendable(storage, assets, Status::Cancelled).await
|
|
}
|
|
}
|
|
|
|
|
|
- pub async fn failed_new_payments_are_not_spendable<'a, T, B>(
|
|
|
|
- storage: &'a T,
|
|
|
|
- assets: AssetManager,
|
|
|
|
- ) where
|
|
|
|
- T: Storage<'a, B>,
|
|
|
|
- B: Batch<'a>,
|
|
|
|
|
|
+ pub async fn failed_new_payments_are_not_spendable<'a, T>(storage: &'a T, assets: AssetManager)
|
|
|
|
+ where
|
|
|
|
+ T: Storage<'a>,
|
|
{
|
|
{
|
|
not_spendable_new_payments_not_spendable(storage, assets, Status::Failed).await
|
|
not_spendable_new_payments_not_spendable(storage, assets, Status::Failed).await
|
|
}
|
|
}
|
|
|
|
|
|
- pub async fn does_not_spend_unspendable_payments<'a, T, B>(storage: &'a T, assets: AssetManager)
|
|
|
|
|
|
+ pub async fn does_not_spend_unspendable_payments<'a, T>(storage: &'a T, assets: AssetManager)
|
|
where
|
|
where
|
|
- T: Storage<'a, B>,
|
|
|
|
- B: Batch<'a>,
|
|
|
|
|
|
+ T: Storage<'a>,
|
|
{
|
|
{
|
|
let mut writer = storage.begin().await.expect("writer");
|
|
let mut writer = storage.begin().await.expect("writer");
|
|
let mut rng = rand::thread_rng();
|
|
let mut rng = rand::thread_rng();
|
|
@@ -421,10 +409,9 @@ pub mod test {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- pub async fn sorted_unspent_payments<'a, T, B>(storage: &'a T, assets: AssetManager)
|
|
|
|
|
|
+ pub async fn sorted_unspent_payments<'a, T>(storage: &'a T, assets: AssetManager)
|
|
where
|
|
where
|
|
- T: Storage<'a, B>,
|
|
|
|
- B: Batch<'a>,
|
|
|
|
|
|
+ T: Storage<'a>,
|
|
{
|
|
{
|
|
let mut writer = storage.begin().await.expect("writer");
|
|
let mut writer = storage.begin().await.expect("writer");
|
|
let accounts: Vec<AccountId> = (0..10)
|
|
let accounts: Vec<AccountId> = (0..10)
|
|
@@ -484,10 +471,9 @@ pub mod test {
|
|
assert!(at_least_one_negative_amount);
|
|
assert!(at_least_one_negative_amount);
|
|
}
|
|
}
|
|
|
|
|
|
- pub async fn relate_account_to_transaction<'a, T, B>(storage: &'a T, assets: AssetManager)
|
|
|
|
|
|
+ pub async fn relate_account_to_transaction<'a, T>(storage: &'a T, assets: AssetManager)
|
|
where
|
|
where
|
|
- T: Storage<'a, B>,
|
|
|
|
- B: Batch<'a>,
|
|
|
|
|
|
+ T: Storage<'a>,
|
|
{
|
|
{
|
|
let account1: AccountId = "alice1".parse().expect("account");
|
|
let account1: AccountId = "alice1".parse().expect("account");
|
|
let account2: AccountId = "alice2".parse().expect("account");
|
|
let account2: AccountId = "alice2".parse().expect("account");
|
|
@@ -553,13 +539,12 @@ pub mod test {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- async fn not_spendable_new_payments_not_spendable<'a, T, B>(
|
|
|
|
|
|
+ async fn not_spendable_new_payments_not_spendable<'a, T>(
|
|
storage: &'a T,
|
|
storage: &'a T,
|
|
assets: AssetManager,
|
|
assets: AssetManager,
|
|
status: Status,
|
|
status: Status,
|
|
) where
|
|
) where
|
|
- T: Storage<'a, B>,
|
|
|
|
- B: Batch<'a>,
|
|
|
|
|
|
+ T: Storage<'a>,
|
|
{
|
|
{
|
|
let mut writer = storage.begin().await.expect("writer");
|
|
let mut writer = storage.begin().await.expect("writer");
|
|
let mut rng = rand::thread_rng();
|
|
let mut rng = rand::thread_rng();
|