use std::sync::Arc;
use snops_common::{aot_cmds::Authorization, format::PackedUint};
use super::{error::CannonError, status::TransactionSendState};
use crate::{db::TxEntry, state::GlobalState};
#[derive(Debug, Clone)]
pub struct TransactionTracker {
pub index: u64,
pub authorization: Option<Arc<Authorization>>,
pub transaction: Option<Arc<serde_json::Value>>,
pub status: TransactionSendState,
}
impl TransactionTracker {
pub fn write_index(state: &GlobalState, key: &TxEntry, index: u64) -> Result<(), CannonError> {
Ok(state.db.tx_index.save(key, &PackedUint(index))?)
}
pub fn inc_attempts(state: &GlobalState, key: &TxEntry) -> Result<(), CannonError> {
let prev = state.db.tx_attempts.restore(key)?.map(|v| v.0).unwrap_or(0);
Ok(state.db.tx_attempts.save(key, &PackedUint(prev + 1))?)
}
pub fn get_attempts(state: &GlobalState, key: &TxEntry) -> u32 {
state
.db
.tx_attempts
.restore(key)
.ok()
.flatten()
.map(|v| v.0 as u32)
.unwrap_or(0)
}
pub fn clear_attempts(state: &GlobalState, key: &TxEntry) -> Result<(), CannonError> {
state.db.tx_attempts.delete(key)?;
Ok(())
}
pub fn write_status(
state: &GlobalState,
key: &TxEntry,
status: TransactionSendState,
) -> Result<(), CannonError> {
Ok(state.db.tx_status.save(key, &status)?)
}
pub fn write_auth(
state: &GlobalState,
key: &TxEntry,
auth: &Authorization,
) -> Result<(), CannonError> {
Ok(state.db.tx_auths.save(key, auth)?)
}
pub fn write_tx(
state: &GlobalState,
key: &TxEntry,
tx: &serde_json::Value,
) -> Result<(), CannonError> {
Ok(state.db.tx_blobs.save(key, tx)?)
}
pub fn write(&self, state: &GlobalState, key: &TxEntry) -> Result<(), CannonError> {
Self::write_index(state, key, self.index)?;
Self::write_status(state, key, self.status)?;
if let Some(auth) = self.authorization.as_deref() {
Self::write_auth(state, key, auth)?;
}
if let Some(tx) = self.transaction.as_deref() {
Self::write_tx(state, key, tx)?;
}
Ok(())
}
pub fn delete(state: &GlobalState, key: &TxEntry) -> Result<(), CannonError> {
state.db.tx_index.delete(key)?;
state.db.tx_attempts.delete(key)?;
state.db.tx_status.delete(key)?;
state.db.tx_auths.delete(key)?;
state.db.tx_blobs.delete(key)?;
Ok(())
}
}