Browse Source

Introduced a rev-id

Cesar Rodas 1 year ago
parent
commit
c26f2d560c

+ 2 - 2
utxo/docs/65cdd331-aa64-48bf-9224-0e1e13c68e41.md

@@ -10,10 +10,10 @@ Each `payment` is a data structure with this information
 
 ```
 struct Payment {
-    created_by_transaction: RevisionId,
+    created_by_transaction: TxId,
     amount: Amount,
     destination: Address,
-    spend_by: Option<RevisionId>
+    spend_by: Option<TxId>
 }
 ```
 

+ 4 - 3
utxo/src/id/mod.rs

@@ -61,15 +61,16 @@ impl<'de, const MAX_LENGTH: usize> de::Deserialize<'de> for MaxLengthString<MAX_
 
 /// The AccountId data type
 pub type AccountId = MaxLengthString<64>;
-crate::BinaryId!(RevisionId, "tx");
+crate::BinaryId!(TxId, "tx-");
+crate::BinaryId!(RevId, "rev-");
 
 /// A generic ID wrapper
 ///
 /// This enum can be used whenever a human ID is passed and needs to be parsed and validated.
 #[derive(Debug)]
 pub enum AnyId {
-    /// RevisionId
-    Transaction(RevisionId),
+    /// TxId
+    Transaction(TxId),
     /// Payment
     Payment(PaymentId),
     /// Account ID

+ 2 - 2
utxo/src/id/payment.rs

@@ -1,4 +1,4 @@
-use crate::{id::Error, RevisionId};
+use crate::{id::Error, TxId};
 use serde::{de, Serialize, Serializer};
 use std::{fmt, ops::Deref, str::FromStr};
 
@@ -10,7 +10,7 @@ use std::{fmt, ops::Deref, str::FromStr};
 /// transaction.
 pub struct PaymentId {
     /// Transaction which created this payment
-    pub transaction: RevisionId,
+    pub transaction: TxId,
     /// This payment position inside the transaction
     pub position: u16,
 }

+ 3 - 4
utxo/src/ledger.rs

@@ -1,7 +1,6 @@
 use crate::{
     amount::AmountCents, config::Config, status::StatusManager, storage::Storage,
-    transaction::Type, AccountId, Amount, Error, PaymentFrom, PaymentId, RevisionId, Status,
-    Transaction,
+    transaction::Type, AccountId, Amount, Error, PaymentFrom, PaymentId, Status, Transaction, TxId,
 };
 use std::{cmp::Ordering, collections::HashMap, sync::Arc};
 
@@ -268,7 +267,7 @@ where
     }
 
     /// Returns the transaction object by a given transaction id
-    pub async fn get_transaction(&self, transaction_id: &RevisionId) -> Result<Transaction, Error> {
+    pub async fn get_transaction(&self, transaction_id: &TxId) -> Result<Transaction, Error> {
         Ok(self.config.storage.get_transaction(transaction_id).await?)
     }
 
@@ -301,7 +300,7 @@ where
     /// new transaction object is returned, otherwise an error is returned.
     pub async fn change_status(
         &self,
-        transaction_id: &RevisionId,
+        transaction_id: &TxId,
         new_status: Status,
         reason: String,
     ) -> Result<Transaction, Error> {

+ 10 - 13
utxo/src/storage/cache/batch.rs

@@ -2,13 +2,13 @@ use super::CacheStorage;
 use crate::{
     payment::PaymentTo,
     storage::{Batch, Error, Status},
-    AccountId, Amount, PaymentFrom, PaymentId, RevisionId, Transaction,
+    AccountId, Amount, PaymentFrom, PaymentId, Transaction, TxId,
 };
 use std::{collections::HashMap, marker::PhantomData};
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub enum Ids {
-    Transaction(RevisionId),
+    Transaction(TxId),
     Payment(PaymentId),
     Account(AccountId),
 }
@@ -20,7 +20,7 @@ where
     inner: B,
     payments: CacheStorage<PaymentId, PaymentFrom>,
     balances: CacheStorage<AccountId, Vec<Amount>>,
-    transactions: CacheStorage<RevisionId, Transaction>,
+    transactions: CacheStorage<TxId, Transaction>,
     to_invalidate: HashMap<Ids, ()>,
     _phantom: PhantomData<&'a ()>,
 }
@@ -33,7 +33,7 @@ where
         batch: B,
         payments: CacheStorage<PaymentId, PaymentFrom>,
         balances: CacheStorage<AccountId, Vec<Amount>>,
-        transactions: CacheStorage<RevisionId, Transaction>,
+        transactions: CacheStorage<TxId, Transaction>,
     ) -> Self {
         Self {
             inner: batch,
@@ -77,14 +77,14 @@ where
 
     async fn get_and_lock_transaction(
         &mut self,
-        transaction_id: &RevisionId,
+        transaction_id: &TxId,
     ) -> Result<Transaction, Error> {
         self.inner.get_and_lock_transaction(transaction_id).await
     }
 
     async fn relate_account_to_transaction(
         &mut self,
-        transaction_id: &RevisionId,
+        transaction_id: &TxId,
         account: &AccountId,
         typ: crate::Type,
     ) -> Result<(), Error> {
@@ -102,7 +102,7 @@ where
 
     async fn update_transaction_payments(
         &mut self,
-        transaction_id: &RevisionId,
+        transaction_id: &TxId,
         create_status: Status,
         spend_status: Status,
     ) -> Result<(usize, usize), Error> {
@@ -113,10 +113,7 @@ where
             .await
     }
 
-    async fn get_payment_status(
-        &mut self,
-        transaction_id: &RevisionId,
-    ) -> Result<Option<Status>, Error> {
+    async fn get_payment_status(&mut self, transaction_id: &TxId) -> Result<Option<Status>, Error> {
         self.to_invalidate
             .insert(Ids::Transaction(transaction_id.clone()), ());
         self.inner.get_payment_status(transaction_id).await
@@ -124,7 +121,7 @@ where
 
     async fn spend_payments(
         &mut self,
-        transaction_id: &RevisionId,
+        transaction_id: &TxId,
         spends: Vec<PaymentId>,
         status: Status,
     ) -> Result<(), Error> {
@@ -138,7 +135,7 @@ where
 
     async fn create_payments(
         &mut self,
-        transaction_id: &RevisionId,
+        transaction_id: &TxId,
         recipients: &[PaymentTo],
         status: Status,
     ) -> Result<(), Error> {

+ 3 - 3
utxo/src/storage/cache/mod.rs

@@ -3,7 +3,7 @@ use crate::{
     amount::AmountCents,
     storage::{Error, Storage},
     transaction::Transaction,
-    AccountId, Amount, Asset, PaymentFrom, PaymentId, RevisionId, Type,
+    AccountId, Amount, Asset, PaymentFrom, PaymentId, TxId, Type,
 };
 use std::{collections::HashMap, sync::Arc};
 use tokio::sync::RwLock;
@@ -23,7 +23,7 @@ where
 {
     payments: CacheStorage<PaymentId, PaymentFrom>,
     balances: CacheStorage<AccountId, Vec<Amount>>,
-    transactions: CacheStorage<RevisionId, Transaction>,
+    transactions: CacheStorage<TxId, Transaction>,
     inner: S,
 }
 
@@ -75,7 +75,7 @@ where
         }
     }
 
-    async fn get_transaction(&self, id: &RevisionId) -> Result<Transaction, Error> {
+    async fn get_transaction(&self, id: &TxId) -> Result<Transaction, Error> {
         let transactions = self.transactions.read().await;
         if let Some(transaction) = transactions.get(id).cloned() {
             Ok(transaction)

+ 15 - 18
utxo/src/storage/mod.rs

@@ -1,7 +1,7 @@
 //! Storage layer trait
 use crate::{
     amount::AmountCents, payment::PaymentTo, transaction::Type, AccountId, Amount, Asset,
-    PaymentFrom, PaymentId, RevisionId, Transaction,
+    PaymentFrom, PaymentId, Transaction, TxId,
 };
 //use chrono::{DateTime, Utc};
 use serde::Serialize;
@@ -108,13 +108,13 @@ pub trait Batch<'a> {
     /// committed.
     async fn get_and_lock_transaction(
         &mut self,
-        transaction_id: &RevisionId,
+        transaction_id: &TxId,
     ) -> Result<Transaction, Error>;
 
     /// Flag the given payments as spent by the given transaction.
     async fn spend_payments(
         &mut self,
-        transaction_id: &RevisionId,
+        transaction_id: &TxId,
         spends: Vec<PaymentId>,
         status: Status,
     ) -> Result<(), Error>;
@@ -122,7 +122,7 @@ pub trait Batch<'a> {
     /// Create a new list of payments
     async fn create_payments(
         &mut self,
-        transaction_id: &RevisionId,
+        transaction_id: &TxId,
         recipients: &[PaymentTo],
         status: Status,
     ) -> Result<(), Error>;
@@ -136,16 +136,13 @@ pub trait Batch<'a> {
     /// from NotSpentable to Spendable can only be done by the parent transaction, and not other.
     async fn update_transaction_payments(
         &mut self,
-        transaction_id: &RevisionId,
+        transaction_id: &TxId,
         create_status: Status,
         spend_status: Status,
     ) -> Result<(usize, usize), Error>;
 
     /// Returns the stats of a payment from the point of view of the on-going transaction
-    async fn get_payment_status(
-        &mut self,
-        transaction_id: &RevisionId,
-    ) -> Result<Option<Status>, Error>;
+    async fn get_payment_status(&mut self, transaction_id: &TxId) -> Result<Option<Status>, Error>;
 
     /// Stores a transaction
     async fn store_transaction(&mut self, transaction: &Transaction) -> Result<(), Error>;
@@ -166,7 +163,7 @@ pub trait Batch<'a> {
     /// layer.
     async fn relate_account_to_transaction(
         &mut self,
-        transaction: &RevisionId,
+        transaction: &TxId,
         account: &AccountId,
         typ: Type,
     ) -> Result<(), Error>;
@@ -213,17 +210,17 @@ pub trait Storage {
 
     /*
     ///
-    async fn get_revision(&self, revision_id: &RevisionId) -> Result<Transaction, Error>;
+    async fn get_revision(&self, revision_id: &TxId) -> Result<Transaction, Error>;
 
     ///
     async fn get_all_revisions(
         &self,
-        transaction_id: &RevisionId,
-    ) -> Result<Vec<(RevisionId, String, DateTime<Utc>)>, Error>;
+        transaction_id: &TxId,
+    ) -> Result<Vec<(TxId, String, DateTime<Utc>)>, Error>;
     */
 
     /// Returns a transaction object by id
-    async fn get_transaction(&self, transaction_id: &RevisionId) -> Result<Transaction, Error>;
+    async fn get_transaction(&self, transaction_id: &TxId) -> Result<Transaction, Error>;
 
     /// Returns a list of a transactions for a given account (and optionally
     /// filter by types). The list of transactions is expected to be sorted by
@@ -427,7 +424,7 @@ pub mod test {
             .expect("valid amount");
 
         for (i, status) in [Status::Locked, Status::Spendable].into_iter().enumerate() {
-            let transaction_id: RevisionId = vec![i as u8; 32].try_into().expect("valid tx id");
+            let transaction_id: TxId = vec![i as u8; 32].try_into().expect("valid tx id");
 
             writer
                 .create_payments(
@@ -470,7 +467,7 @@ pub mod test {
             .expect("valid amount");
 
         for (i, status) in [Status::Failed, Status::Spent].into_iter().enumerate() {
-            let transaction_id: RevisionId = vec![i as u8; 32].try_into().expect("valid tx id");
+            let transaction_id: TxId = vec![i as u8; 32].try_into().expect("valid tx id");
 
             writer
                 .create_payments(
@@ -517,7 +514,7 @@ pub mod test {
         let usd: Asset = "USD/2".parse().expect("valid asset");
 
         for (index, account) in accounts.iter().enumerate() {
-            let transaction_id: RevisionId = vec![index as u8; 32].try_into().expect("valid tx id");
+            let transaction_id: TxId = vec![index as u8; 32].try_into().expect("valid tx id");
             let recipients = (0..target_inputs_per_account)
                 .map(|_| {
                     let amount = usd
@@ -642,7 +639,7 @@ pub mod test {
             .from_human(&format!("{}", rng.gen_range(10.0..10000.0)))
             .expect("valid amount");
 
-        let transaction: RevisionId = vec![0u8; 32].try_into().expect("valid tx id");
+        let transaction: TxId = vec![0u8; 32].try_into().expect("valid tx id");
 
         writer
             .create_payments(

+ 8 - 12
utxo/src/storage/sqlite/batch.rs

@@ -2,7 +2,7 @@ use crate::{
     payment::PaymentTo,
     storage::{self, Error, Status},
     transaction::inner::Revision,
-    AccountId, PaymentId, RevisionId, Transaction, Type,
+    AccountId, PaymentId, RevId, Transaction, TxId, Type,
 };
 use sqlx::{Row, Sqlite, Transaction as SqlxTransaction};
 use std::{marker::PhantomData, num::TryFromIntError};
@@ -37,7 +37,7 @@ impl<'a> storage::Batch<'a> for Batch<'a> {
 
     async fn relate_account_to_transaction(
         &mut self,
-        transaction: &RevisionId,
+        transaction: &TxId,
         account: &AccountId,
         typ: Type,
     ) -> Result<(), Error> {
@@ -58,7 +58,7 @@ impl<'a> storage::Batch<'a> for Batch<'a> {
 
     async fn get_and_lock_transaction(
         &mut self,
-        transaction_id: &RevisionId,
+        transaction_id: &TxId,
     ) -> Result<Transaction, Error> {
         let row = sqlx::query(
             r#"
@@ -84,11 +84,10 @@ impl<'a> storage::Batch<'a> for Batch<'a> {
         Transaction::from_revision(
             bincode::deserialize::<Revision>(&encoded)
                 .map_err(|e| Error::Storage(e.to_string()))?,
-            Some(transaction_id.clone()),
             Some(
                 row.try_get::<String, usize>(0)
                     .map_err(|e| Error::Storage(e.to_string()))?
-                    .parse::<RevisionId>()
+                    .parse::<RevId>()
                     .map_err(|e| Error::Storage(e.to_string()))?,
             ),
         )
@@ -104,7 +103,7 @@ impl<'a> storage::Batch<'a> for Batch<'a> {
 
     async fn spend_payments(
         &mut self,
-        transaction_id: &RevisionId,
+        transaction_id: &TxId,
         spends: Vec<PaymentId>,
         status: Status,
     ) -> Result<(), Error> {
@@ -146,7 +145,7 @@ impl<'a> storage::Batch<'a> for Batch<'a> {
 
     async fn create_payments(
         &mut self,
-        transaction_id: &RevisionId,
+        transaction_id: &TxId,
         recipients: &[PaymentTo],
         status: Status,
     ) -> Result<(), Error> {
@@ -180,7 +179,7 @@ impl<'a> storage::Batch<'a> for Batch<'a> {
 
     async fn update_transaction_payments(
         &mut self,
-        transaction_id: &RevisionId,
+        transaction_id: &TxId,
         create_status: Status,
         spend_status: Status,
     ) -> Result<(usize, usize), Error> {
@@ -225,10 +224,7 @@ impl<'a> storage::Batch<'a> for Batch<'a> {
         ))
     }
 
-    async fn get_payment_status(
-        &mut self,
-        transaction_id: &RevisionId,
-    ) -> Result<Option<Status>, Error> {
+    async fn get_payment_status(&mut self, transaction_id: &TxId) -> Result<Option<Status>, Error> {
         let row = sqlx::query(
             r#"
             SELECT

+ 11 - 19
utxo/src/storage/sqlite/mod.rs

@@ -3,7 +3,7 @@ use crate::{
     amount::AmountCents,
     storage::{Error, Storage},
     transaction::{inner::Revision, Type},
-    AccountId, Amount, Asset, PaymentFrom, PaymentId, RevisionId, Transaction,
+    AccountId, Amount, Asset, PaymentFrom, PaymentId, RevId, Transaction, TxId,
 };
 use futures::TryStreamExt;
 use sqlx::{sqlite::SqliteRow, Executor, Row};
@@ -36,23 +36,23 @@ impl SQLite {
         x.execute(
             r#"
         CREATE TABLE IF NOT EXISTS "transactions" (
-            "transaction_id" VARCHAR(66) NOT NULL PRIMARY KEY,
-            "revision_id" VARCHAR(66) NOT NULL,
+            "transaction_id" VARCHAR(67) NOT NULL PRIMARY KEY,
+            "revision_id" VARCHAR(68) NOT NULL,
             "status" VARCHAR(10) NOT NULL,
             "created_at" DATETIME DEFAULT CURRENT_TIMESTAMP,
             "updated_at" DATETIME DEFAULT CURRENT_TIMESTAMP
         );
         CREATE TABLE IF NOT EXISTS "revisions" (
-            "revision_id" VARCHAR(64) NOT NULL PRIMARY KEY,
-            "transaction_id" VARCHAR(66) NOT NULL,
+            "revision_id" VARCHAR(68) NOT NULL PRIMARY KEY,
+            "transaction_id" VARCHAR(67) NOT NULL,
             "previous_blob_id" BLOB,
             "status" VARCHAR(30) NOT NULL,
             "blob" BINARY NOT NULL,
             "created_at" DATETIME DEFAULT CURRENT_TIMESTAMP
         );
         CREATE TABLE IF NOT EXISTS "payments" (
-            "payment_id" VARCHAR(70) NOT NULL PRIMARY KEY,
-            "to" VARCHAR(255) NOT NULL,
+            "payment_id" VARCHAR(80) NOT NULL PRIMARY KEY,
+            "to" VARCHAR(64) NOT NULL,
             "status" INT NOT NULL,
             "asset" VARCHAR(10) NOT NULL,
             "cents" STRING NOT NULL,
@@ -233,7 +233,7 @@ impl Storage for SQLite {
         }
     }
 
-    async fn get_transaction(&self, transaction_id: &RevisionId) -> Result<Transaction, Error> {
+    async fn get_transaction(&self, transaction_id: &TxId) -> Result<Transaction, Error> {
         let mut conn = self
             .db
             .acquire()
@@ -265,11 +265,10 @@ impl Storage for SQLite {
         Transaction::from_revision(
             bincode::deserialize::<Revision>(&encoded)
                 .map_err(|e| Error::Storage(e.to_string()))?,
-            Some(transaction_id.clone()),
             Some(
                 row.try_get::<String, usize>(0)
                     .map_err(|e| Error::Storage(e.to_string()))?
-                    .parse::<RevisionId>()
+                    .parse::<RevId>()
                     .map_err(|e| Error::Storage(e.to_string()))?,
             ),
         )
@@ -312,7 +311,6 @@ impl Storage for SQLite {
             format!(
                 r#"SELECT
                     "t"."transaction_id",
-                    "t"."revision_id",
                     "b"."blob"
                 FROM
                     "transaction_accounts" as "ta",
@@ -335,7 +333,7 @@ impl Storage for SQLite {
             .into_iter()
             .map(|row| {
                 let encoded = row
-                    .try_get::<Vec<u8>, usize>(2)
+                    .try_get::<Vec<u8>, usize>(1)
                     .map_err(|e| Error::Storage(e.to_string()))?;
 
                 Transaction::from_revision(
@@ -344,13 +342,7 @@ impl Storage for SQLite {
                     Some(
                         row.try_get::<String, usize>(0)
                             .map_err(|e| Error::Storage(e.to_string()))?
-                            .parse::<RevisionId>()
-                            .map_err(|e| Error::Storage(e.to_string()))?,
-                    ),
-                    Some(
-                        row.try_get::<String, usize>(1)
-                            .map_err(|e| Error::Storage(e.to_string()))?
-                            .parse::<RevisionId>()
+                            .parse::<RevId>()
                             .map_err(|e| Error::Storage(e.to_string()))?,
                     ),
                 )

+ 3 - 3
utxo/src/tests/mod.rs

@@ -1,5 +1,5 @@
 use crate::{
-    storage::sqlite::SQLite, storage::Storage, AccountId, Amount, Error, Ledger, RevisionId, Status,
+    storage::sqlite::SQLite, storage::Storage, AccountId, Amount, Error, Ledger, Status, TxId,
 };
 use sqlx::sqlite::SqlitePoolOptions;
 
@@ -37,7 +37,7 @@ pub async fn withdrawal(
     account_id: &AccountId,
     status: Status,
     amount: Amount,
-) -> Result<RevisionId, Error> {
+) -> Result<TxId, Error> {
     Ok(ledger
         .withdrawal(account_id, amount, status, "Test".to_owned())
         .await?
@@ -45,7 +45,7 @@ pub async fn withdrawal(
         .clone())
 }
 
-pub async fn deposit<S>(ledger: &Ledger<S>, account_id: &AccountId, amount: Amount) -> RevisionId
+pub async fn deposit<S>(ledger: &Ledger<S>, account_id: &AccountId, amount: Amount) -> TxId
 where
     S: Storage + Send + Sync,
 {

+ 2 - 2
utxo/src/transaction/error.rs

@@ -1,4 +1,4 @@
-use crate::{status, storage, Amount, Asset, RevisionId, Status};
+use crate::{status, storage, Amount, Asset, Status, TxId};
 use serde::Serialize;
 
 #[derive(thiserror::Error, Debug, Serialize)]
@@ -42,7 +42,7 @@ pub enum Error {
     NoUpdate,
 
     #[error("Invalid calculated id {0} (expected {1})")]
-    InvalidRevisionId(RevisionId, RevisionId),
+    InvalidTxId(TxId, TxId),
 
     #[error("Overflow")]
     Overflow,

+ 23 - 32
utxo/src/transaction/inner.rs

@@ -4,7 +4,7 @@ use crate::{
     payment::PaymentTo,
     storage::{self, Batch, Storage},
     transaction::*,
-    AccountId, Amount, Asset, PaymentFrom, RevisionId, Status,
+    AccountId, Amount, Asset, PaymentFrom, RevId, Status, TxId,
 };
 use chrono::{serde::ts_milliseconds, DateTime, Utc};
 use serde::{Deserialize, Serialize};
@@ -25,7 +25,7 @@ use std::collections::HashMap;
 pub struct Revision {
     #[serde(rename = "_prev_rev")]
     /// Any previous transaction that this transaction is replacing.
-    previous: Option<RevisionId>,
+    previous: Option<RevId>,
     /// A human-readable description of the transaction changes.
     changelog: String,
     spends: Vec<PaymentFrom>,
@@ -43,23 +43,24 @@ pub struct Revision {
 }
 
 impl Revision {
-    pub fn calculate_id(&self) -> Result<RevisionId, Error> {
+    /// Calculates a revision ID
+    pub fn calculate_rev_id(&self) -> Result<RevId, Error> {
         let mut hasher = Sha256::new();
         let bytes = bincode::serialize(self)?;
         hasher.update(bytes);
-        Ok(RevisionId::new(hasher.finalize().into()))
+        Ok(RevId::new(hasher.finalize().into()))
     }
 
     /// The transaction fingerprint is a hash of the properties that are not allowed to be updated
     /// in a transaction.
-    pub fn transaction_fingerprint(&self) -> Result<RevisionId, Error> {
+    pub fn calculate_id(&self) -> Result<TxId, Error> {
         let mut hasher = Sha256::new();
         hasher.update(&bincode::serialize(&self.spends)?);
         hasher.update(&bincode::serialize(&self.creates)?);
         hasher.update(&self.typ.to_string());
         hasher.update(&self.reference);
         hasher.update(&self.created_at.timestamp_millis().to_string());
-        Ok(RevisionId::new(hasher.finalize().into()))
+        Ok(TxId::new(hasher.finalize().into()))
     }
 
     /// Validates the transaction input and output (debit and credit)
@@ -159,16 +160,16 @@ impl Revision {
 #[derive(Debug, Clone, Serialize)]
 pub struct Transaction {
     #[serde(rename = "_id")]
-    /// The RevisionId is the RevisionID of the first revision of the transaction.
-    pub id: RevisionId,
+    /// The TxId is the TxId of the first revision of the transaction.
+    pub id: TxId,
 
     #[serde(rename = "_rev")]
     /// Current Revision ID.
-    pub revision_id: RevisionId,
+    pub revision_id: RevId,
 
     #[serde(rename = "_latest_rev")]
     /// Latest revision of this transaction
-    pub lastest_revision: RevisionId,
+    pub lastest_revision: RevId,
 
     /// The transaction inner details
     #[serde(flatten)]
@@ -203,7 +204,6 @@ impl Transaction {
                 updated_at: Utc::now(),
             },
             None,
-            None,
         )
     }
 
@@ -229,7 +229,6 @@ impl Transaction {
                 updated_at: Utc::now(),
             },
             None,
-            None,
         )
     }
 
@@ -265,22 +264,19 @@ impl Transaction {
                 updated_at: Utc::now(),
             },
             None,
-            None,
         )
     }
 
     /// Creates a new transaction object from a given revision
     pub fn from_revision(
         revision: Revision,
-        first_revision: Option<RevisionId>,
-        lastest_revision: Option<RevisionId>,
+        lastest_revision: Option<RevId>,
     ) -> Result<Self, Error> {
-        let revision_id = revision.calculate_id()?;
-        let first_revision = first_revision.unwrap_or_else(|| revision_id.clone());
+        let revision_id = revision.calculate_rev_id()?;
         let lastest_revision = lastest_revision.unwrap_or_else(|| revision_id.clone());
 
         Ok(Transaction {
-            id: first_revision,
+            id: revision.calculate_id()?,
             revision_id,
             lastest_revision,
             inner: revision,
@@ -293,7 +289,7 @@ impl Transaction {
     }
 
     /// Returns the previous revision of this transaction, if any
-    pub fn previous(&self) -> Option<RevisionId> {
+    pub fn previous(&self) -> Option<RevId> {
         self.inner.previous.clone()
     }
 
@@ -345,22 +341,18 @@ impl Transaction {
         inner.updated_at = Utc::now();
         inner.previous = Some(self.revision_id);
         inner.status = new_status;
-        let mut x: Transaction = Transaction::from_revision(inner, Some(self.id), None)?;
+        let mut x: Transaction = Transaction::from_revision(inner, None)?;
         x.persist(config).await?;
         Ok(x)
     }
 
     /// Validates the transaction before storing
     pub(crate) fn validate(&self) -> Result<(), Error> {
-        let calculated_revision_id = self.inner.calculate_id()?;
-
-        if self.revision_id != calculated_revision_id
-            || (self.inner.previous.is_none() && self.id != calculated_revision_id)
-        {
-            return Err(Error::InvalidRevisionId(
-                self.id.clone(),
-                calculated_revision_id,
-            ));
+        let calculated_revision_id = self.inner.calculate_rev_id()?;
+        let calculated_tx_id = self.inner.calculate_id()?;
+
+        if self.revision_id != calculated_revision_id || self.id != calculated_tx_id {
+            return Err(Error::InvalidTxId(self.id.clone(), calculated_tx_id));
         }
 
         self.inner.validate()
@@ -377,7 +369,7 @@ impl Transaction {
     }
 
     /// Returns the transaction ID
-    pub fn id(&self) -> &RevisionId {
+    pub fn id(&self) -> &TxId {
         &self.id
     }
 
@@ -422,8 +414,7 @@ impl Transaction {
             let current_transaction = batch.get_and_lock_transaction(&self.id).await?;
 
             if config.status.is_final(&current_transaction.inner.status)
-                || self.inner.transaction_fingerprint()?
-                    != current_transaction.inner.transaction_fingerprint()?
+                || self.inner.calculate_id()? != current_transaction.inner.calculate_id()?
                 || *previous_id != current_transaction.lastest_revision
             {
                 return Err(Error::TransactionUpdatesNotAllowed);