Skip to main content

diem_types/
mempool_status.rs

1// Copyright (c) The Diem Core Contributors
2// SPDX-License-Identifier: Apache-2.0
3
4#![allow(clippy::unit_arg)]
5
6use anyhow::Result;
7#[cfg(any(test, feature = "fuzzing"))]
8use proptest::prelude::*;
9#[cfg(any(test, feature = "fuzzing"))]
10use proptest_derive::Arbitrary;
11use std::{convert::TryFrom, fmt};
12
13/// A `MempoolStatus` is represented as a required status code that is semantic coupled with an optional sub status and message.
14#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
15#[cfg_attr(any(test, feature = "fuzzing"), derive(Arbitrary))]
16#[cfg_attr(any(test, feature = "fuzzing"), proptest(no_params))]
17pub struct MempoolStatus {
18    /// insertion status code
19    pub code: MempoolStatusCode,
20    /// optional message
21    pub message: String,
22}
23
24impl MempoolStatus {
25    pub fn new(code: MempoolStatusCode) -> Self {
26        Self {
27            code,
28            message: "".to_string(),
29        }
30    }
31
32    /// Adds a message to the Mempool status.
33    pub fn with_message(mut self, message: String) -> Self {
34        self.message = message;
35        self
36    }
37}
38
39impl fmt::Display for MempoolStatus {
40    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41        write!(f, "{}", &self.code)?;
42        if !self.message.is_empty() {
43            write!(f, " - {}", &self.message)?;
44        }
45        Ok(())
46    }
47}
48
49#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
50#[cfg_attr(any(test, feature = "fuzzing"), derive(Arbitrary))]
51#[repr(u64)]
52pub enum MempoolStatusCode {
53    // Transaction was accepted by Mempool
54    Accepted = 0,
55    // Sequence number is old, etc.
56    InvalidSeqNumber = 1,
57    // Mempool is full (reached max global capacity)
58    MempoolIsFull = 2,
59    // Account reached max capacity per account
60    TooManyTransactions = 3,
61    // Invalid update. Only gas price increase is allowed
62    InvalidUpdate = 4,
63    // transaction didn't pass vm_validation
64    VmError = 5,
65    UnknownStatus = 6,
66}
67
68impl TryFrom<u64> for MempoolStatusCode {
69    type Error = &'static str;
70
71    fn try_from(value: u64) -> Result<Self, Self::Error> {
72        match value {
73            0 => Ok(MempoolStatusCode::Accepted),
74            1 => Ok(MempoolStatusCode::InvalidSeqNumber),
75            2 => Ok(MempoolStatusCode::MempoolIsFull),
76            3 => Ok(MempoolStatusCode::TooManyTransactions),
77            4 => Ok(MempoolStatusCode::InvalidUpdate),
78            5 => Ok(MempoolStatusCode::VmError),
79            6 => Ok(MempoolStatusCode::UnknownStatus),
80            _ => Err("invalid StatusCode"),
81        }
82    }
83}
84
85impl From<MempoolStatusCode> for u64 {
86    fn from(status: MempoolStatusCode) -> u64 {
87        status as u64
88    }
89}
90
91impl fmt::Display for MempoolStatusCode {
92    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
93        write!(f, "{:?}", self)
94    }
95}