casper_types/transaction/
transaction_id.rs

1use alloc::vec::Vec;
2use core::fmt::{self, Display, Formatter};
3
4#[cfg(feature = "datasize")]
5use datasize::DataSize;
6use serde::{Deserialize, Serialize};
7
8#[cfg(doc)]
9use super::Transaction;
10use super::{ApprovalsHash, TransactionHash};
11use crate::bytesrepr::{self, FromBytes, ToBytes};
12#[cfg(any(feature = "testing", test))]
13use crate::testing::TestRng;
14
15/// The unique identifier of a [`Transaction`], comprising its [`TransactionHash`] and
16/// [`ApprovalsHash`].
17#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Serialize, Deserialize, Debug)]
18#[cfg_attr(feature = "datasize", derive(DataSize))]
19#[serde(deny_unknown_fields)]
20pub struct TransactionId {
21    /// The transaction hash.
22    transaction_hash: TransactionHash,
23    /// The approvals hash.
24    approvals_hash: ApprovalsHash,
25}
26
27impl TransactionId {
28    /// Returns a new `TransactionId`.
29    pub fn new(transaction_hash: TransactionHash, approvals_hash: ApprovalsHash) -> Self {
30        TransactionId {
31            transaction_hash,
32            approvals_hash,
33        }
34    }
35
36    /// Returns the transaction hash.
37    pub fn transaction_hash(&self) -> TransactionHash {
38        self.transaction_hash
39    }
40
41    /// Returns the approvals hash.
42    pub fn approvals_hash(&self) -> ApprovalsHash {
43        self.approvals_hash
44    }
45
46    /// Returns a random `TransactionId`.
47    #[cfg(any(feature = "testing", test))]
48    pub fn random(rng: &mut TestRng) -> Self {
49        TransactionId::new(TransactionHash::random(rng), ApprovalsHash::random(rng))
50    }
51}
52
53impl Display for TransactionId {
54    fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
55        write!(
56            formatter,
57            "transaction-id({}, {})",
58            self.transaction_hash(),
59            self.approvals_hash()
60        )
61    }
62}
63
64impl ToBytes for TransactionId {
65    fn write_bytes(&self, writer: &mut Vec<u8>) -> Result<(), bytesrepr::Error> {
66        self.transaction_hash.write_bytes(writer)?;
67        self.approvals_hash.write_bytes(writer)
68    }
69
70    fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> {
71        let mut buffer = bytesrepr::allocate_buffer(self)?;
72        self.write_bytes(&mut buffer)?;
73        Ok(buffer)
74    }
75
76    fn serialized_length(&self) -> usize {
77        self.transaction_hash.serialized_length() + self.approvals_hash.serialized_length()
78    }
79}
80
81impl FromBytes for TransactionId {
82    fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> {
83        let (transaction_hash, rem) = TransactionHash::from_bytes(bytes)?;
84        let (approvals_hash, rem) = ApprovalsHash::from_bytes(rem)?;
85        let transaction_id = TransactionId::new(transaction_hash, approvals_hash);
86        Ok((transaction_id, rem))
87    }
88}
89
90#[cfg(test)]
91mod tests {
92    use super::*;
93
94    #[test]
95    fn bytesrepr_roundtrip() {
96        let rng = &mut TestRng::new();
97        let id = TransactionId::random(rng);
98        bytesrepr::test_serialization_roundtrip(&id);
99    }
100}