snarkos_node_router_messages/
unconfirmed_transaction.rs1use super::*;
17
18use snarkvm::{
19 ledger::narwhal::Data,
20 prelude::{FromBytes, ToBytes},
21};
22
23use std::borrow::Cow;
24
25#[derive(Clone, Debug, PartialEq, Eq)]
26pub struct UnconfirmedTransaction<N: Network> {
27 pub transaction_id: N::TransactionID,
28 pub transaction: Data<Transaction<N>>,
29}
30
31impl<N: Network> From<Transaction<N>> for UnconfirmedTransaction<N> {
32 fn from(transaction: Transaction<N>) -> Self {
34 Self { transaction_id: transaction.id(), transaction: Data::Object(transaction) }
35 }
36}
37
38impl<N: Network> MessageTrait for UnconfirmedTransaction<N> {
39 #[inline]
41 fn name(&self) -> Cow<'static, str> {
42 "UnconfirmedTransaction".into()
43 }
44}
45
46impl<N: Network> ToBytes for UnconfirmedTransaction<N> {
47 fn write_le<W: io::Write>(&self, mut writer: W) -> io::Result<()> {
48 self.transaction_id.write_le(&mut writer)?;
49 self.transaction.write_le(&mut writer)?;
50 Ok(())
51 }
52}
53
54impl<N: Network> FromBytes for UnconfirmedTransaction<N> {
55 fn read_le<R: io::Read>(mut reader: R) -> io::Result<Self> {
56 Ok(Self { transaction_id: N::TransactionID::read_le(&mut reader)?, transaction: Data::read_le(reader)? })
57 }
58}
59
60#[cfg(test)]
61pub mod prop_tests {
62 use crate::{Transaction, UnconfirmedTransaction};
63 use snarkvm::{
64 ledger::{
65 narwhal::Data,
66 test_helpers::{sample_fee_public_transaction, sample_large_execution_transaction},
67 },
68 prelude::{FromBytes, TestRng, ToBytes},
69 };
70
71 use bytes::{Buf, BufMut, BytesMut};
72 use proptest::prelude::{BoxedStrategy, Strategy, any};
73 use test_strategy::proptest;
74
75 type CurrentNetwork = snarkvm::prelude::MainnetV0;
76
77 pub fn any_transaction() -> BoxedStrategy<Transaction<CurrentNetwork>> {
78 any::<u64>()
79 .prop_map(|seed| {
80 let mut rng = TestRng::fixed(seed);
81 sample_fee_public_transaction(&mut rng)
82 })
83 .boxed()
84 }
85
86 pub fn any_large_transaction() -> BoxedStrategy<Transaction<CurrentNetwork>> {
87 any::<u64>()
88 .prop_map(|seed| {
89 let mut rng = TestRng::fixed(seed);
90 sample_large_execution_transaction(&mut rng)
91 })
92 .boxed()
93 }
94
95 pub fn any_unconfirmed_transaction() -> BoxedStrategy<UnconfirmedTransaction<CurrentNetwork>> {
96 any_transaction()
97 .prop_map(|tx| UnconfirmedTransaction { transaction_id: tx.id(), transaction: Data::Object(tx) })
98 .boxed()
99 }
100
101 pub fn any_large_unconfirmed_transaction() -> BoxedStrategy<UnconfirmedTransaction<CurrentNetwork>> {
102 any_large_transaction()
103 .prop_map(|tx| UnconfirmedTransaction { transaction_id: tx.id(), transaction: Data::Object(tx) })
104 .boxed()
105 }
106
107 #[proptest]
108 fn unconfirmed_transaction_roundtrip(
109 #[strategy(any_unconfirmed_transaction())] original: UnconfirmedTransaction<CurrentNetwork>,
110 ) {
111 let mut buf = BytesMut::default().writer();
112 UnconfirmedTransaction::write_le(&original, &mut buf).unwrap();
113
114 let deserialized: UnconfirmedTransaction<CurrentNetwork> =
115 UnconfirmedTransaction::read_le(buf.into_inner().reader()).unwrap();
116 assert_eq!(original.transaction_id, deserialized.transaction_id);
117 assert_eq!(
118 original.transaction.deserialize_blocking().unwrap(),
119 deserialized.transaction.deserialize_blocking().unwrap(),
120 );
121 }
122}