delta_base_sdk/
transactions.rs

1//! Types and utilities for creating, and signing transactions.
2//!
3//! This module provides everything needed to construct, sign, and submit
4//! transactions in delta. It includes a builder interface for creating
5//! transactions and types for tracking transaction status.
6
7use primitives::type_aliases::Shard;
8use proto_types::{
9    error::{
10        MissingDataSnafu,
11        ProtoError,
12    },
13    transactions::TxFailed,
14};
15use snafu::OptionExt;
16use std::fmt::Display;
17
18// Re-export required types
19pub use primitives::{
20    constants::MIN_NEW_SHARD_FEE,
21    domain_agreement::DomainAgreement,
22    transaction::*,
23};
24pub use proto_types::transactions::TypeData;
25
26/// Information about a failed transaction.
27#[derive(Debug, Clone, PartialEq, Eq)]
28pub struct FailureInfo {
29    /// The kind of failure that occurred.
30    pub kind: FailureKind,
31    /// The originator shard of the transaction that failed, if known.
32    pub originator_shard: Option<Shard>,
33}
34
35/// Reasons why a transaction has failed.
36#[derive(Debug, Clone, PartialEq, Eq)]
37pub enum FailureKind {
38    /// The base-layer rejected the transaction because of its epoch.
39    WrongEpoch,
40    /// The base-layer rejected the transaction for any other reason.
41    Other {
42        /// The reason why the transaction failed.
43        reason: String,
44    },
45}
46
47/// The status of a base-layer stored transaction
48#[derive(Debug, Clone, PartialEq, Eq)]
49pub enum TransactionStatus {
50    /// The transaction is still processing.
51    Pending,
52    /// The transaction was successfully processed.
53    Applied,
54    /// The transaction failed processing, and reason why.
55    // TODO we should be able to use FailureInfo here
56    Failure(String),
57}
58
59impl Display for TransactionStatus {
60    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
61        match self {
62            Self::Pending => write!(f, "PENDING"),
63            Self::Applied => write!(f, "APPLIED"),
64            Self::Failure(error) => write!(f, "FAILED ({error})"),
65        }
66    }
67}
68
69impl TryFrom<proto_types::transactions::TransactionStatus> for TransactionStatus {
70    type Error = ProtoError;
71
72    fn try_from(value: proto_types::transactions::TransactionStatus) -> Result<Self, Self::Error> {
73        use proto_types::transactions::Status;
74        let status = value.status.context(MissingDataSnafu { field: "status" })?;
75        Ok(match status {
76            Status::Pending(..) => Self::Pending,
77            Status::Applied(..) => Self::Applied,
78            Status::Failed(TxFailed { error }) => Self::Failure(error),
79        })
80    }
81}