use crate::proto::base_node as proto;
use serde::{Deserialize, Serialize};
use std::{
convert::TryFrom,
fmt::{Display, Error, Formatter},
};
use tari_common_types::types::BlockHash;
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct TxSubmissionResponse {
pub accepted: bool,
pub rejection_reason: TxSubmissionRejectionReason,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum TxSubmissionRejectionReason {
None,
AlreadyMined,
DoubleSpend,
Orphan,
TimeLocked,
ValidationFailed,
}
impl Display for TxSubmissionRejectionReason {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
let response = match self {
TxSubmissionRejectionReason::AlreadyMined => "Already Mined ",
TxSubmissionRejectionReason::DoubleSpend => "Double Spend",
TxSubmissionRejectionReason::Orphan => "Orphan",
TxSubmissionRejectionReason::TimeLocked => "Time Locked",
TxSubmissionRejectionReason::ValidationFailed => "Validation Failed",
TxSubmissionRejectionReason::None => "None",
};
fmt.write_str(&response)
}
}
impl TryFrom<proto::TxSubmissionRejectionReason> for TxSubmissionRejectionReason {
type Error = String;
fn try_from(tx_rejection_reason: proto::TxSubmissionRejectionReason) -> Result<Self, Self::Error> {
use proto::TxSubmissionRejectionReason::*;
Ok(match tx_rejection_reason {
None => TxSubmissionRejectionReason::None,
AlreadyMined => TxSubmissionRejectionReason::AlreadyMined,
DoubleSpend => TxSubmissionRejectionReason::DoubleSpend,
Orphan => TxSubmissionRejectionReason::Orphan,
TimeLocked => TxSubmissionRejectionReason::TimeLocked,
ValidationFailed => TxSubmissionRejectionReason::ValidationFailed,
})
}
}
impl From<TxSubmissionRejectionReason> for proto::TxSubmissionRejectionReason {
fn from(resp: TxSubmissionRejectionReason) -> Self {
use TxSubmissionRejectionReason::*;
match resp {
None => proto::TxSubmissionRejectionReason::None,
AlreadyMined => proto::TxSubmissionRejectionReason::AlreadyMined,
DoubleSpend => proto::TxSubmissionRejectionReason::DoubleSpend,
Orphan => proto::TxSubmissionRejectionReason::Orphan,
TimeLocked => proto::TxSubmissionRejectionReason::TimeLocked,
ValidationFailed => proto::TxSubmissionRejectionReason::ValidationFailed,
}
}
}
impl TryFrom<proto::TxSubmissionResponse> for TxSubmissionResponse {
type Error = String;
fn try_from(value: proto::TxSubmissionResponse) -> Result<Self, Self::Error> {
Ok(Self {
accepted: value.accepted,
rejection_reason: TxSubmissionRejectionReason::try_from(
proto::TxSubmissionRejectionReason::from_i32(value.rejection_reason)
.ok_or_else(|| "Invalid or unrecognised `TxSubmissionRejectionReason` enum".to_string())?,
)?,
})
}
}
impl From<TxSubmissionResponse> for proto::TxSubmissionResponse {
fn from(value: TxSubmissionResponse) -> Self {
Self {
accepted: value.accepted,
rejection_reason: proto::TxSubmissionRejectionReason::from(value.rejection_reason) as i32,
}
}
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct TxQueryResponse {
pub location: TxLocation,
pub block_hash: Option<BlockHash>,
pub confirmations: u64,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum TxLocation {
NotStored,
InMempool,
Mined,
}
impl Display for TxLocation {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
let response = match self {
TxLocation::NotStored => "Not Stored",
TxLocation::InMempool => "In Mempool",
TxLocation::Mined => "Mined",
};
fmt.write_str(&response)
}
}
impl TryFrom<proto::TxLocation> for TxLocation {
type Error = String;
fn try_from(tx_location: proto::TxLocation) -> Result<Self, Self::Error> {
use proto::TxLocation::*;
Ok(match tx_location {
None => return Err("TxLocation not provided".to_string()),
NotStored => TxLocation::NotStored,
InMempool => TxLocation::InMempool,
Mined => TxLocation::Mined,
})
}
}
impl From<TxLocation> for proto::TxLocation {
fn from(resp: TxLocation) -> Self {
use TxLocation::*;
match resp {
NotStored => proto::TxLocation::NotStored,
InMempool => proto::TxLocation::InMempool,
Mined => proto::TxLocation::Mined,
}
}
}
impl TryFrom<proto::TxQueryResponse> for TxQueryResponse {
type Error = String;
fn try_from(proto_response: proto::TxQueryResponse) -> Result<Self, Self::Error> {
Ok(Self {
location: TxLocation::try_from(
proto::TxLocation::from_i32(proto_response.location)
.ok_or_else(|| "Invalid or unrecognised `TxLocation` enum".to_string())?,
)?,
block_hash: proto_response.block_hash,
confirmations: proto_response.confirmations,
})
}
}
impl From<TxQueryResponse> for proto::TxQueryResponse {
fn from(response: TxQueryResponse) -> Self {
Self {
location: proto::TxLocation::from(response.location) as i32,
block_hash: response.block_hash,
confirmations: response.confirmations,
}
}
}