kaspa_p2p_lib/convert/
tx.rs1use super::{error::ConversionError, option::TryIntoOptionEx};
2use crate::pb as protowire;
3use kaspa_consensus_core::{
4 subnets::SubnetworkId,
5 tx::{ScriptPublicKey, Transaction, TransactionId, TransactionInput, TransactionOutpoint, TransactionOutput, UtxoEntry},
6};
7use kaspa_hashes::Hash;
8
9impl From<Hash> for protowire::TransactionId {
14 fn from(hash: Hash) -> Self {
15 Self { bytes: Vec::from(hash.as_bytes()) }
16 }
17}
18
19impl From<&Hash> for protowire::TransactionId {
20 fn from(hash: &Hash) -> Self {
21 Self { bytes: Vec::from(hash.as_bytes()) }
22 }
23}
24
25impl From<&SubnetworkId> for protowire::SubnetworkId {
26 fn from(id: &SubnetworkId) -> Self {
27 Self { bytes: Vec::from(<SubnetworkId as AsRef<[u8]>>::as_ref(id)) }
28 }
29}
30
31impl From<&TransactionOutpoint> for protowire::Outpoint {
32 fn from(outpoint: &TransactionOutpoint) -> Self {
33 Self { transaction_id: Some(outpoint.transaction_id.into()), index: outpoint.index }
34 }
35}
36
37impl From<&ScriptPublicKey> for protowire::ScriptPublicKey {
38 fn from(script_public_key: &ScriptPublicKey) -> Self {
39 Self { script: script_public_key.script().to_vec(), version: script_public_key.version() as u32 }
40 }
41}
42
43impl From<&TransactionInput> for protowire::TransactionInput {
44 fn from(input: &TransactionInput) -> Self {
45 Self {
46 previous_outpoint: Some((&input.previous_outpoint).into()),
47 signature_script: input.signature_script.clone(),
48 sequence: input.sequence,
49 sig_op_count: input.sig_op_count as u32,
50 }
51 }
52}
53
54impl From<&TransactionOutput> for protowire::TransactionOutput {
55 fn from(output: &TransactionOutput) -> Self {
56 Self { value: output.value, script_public_key: Some((&output.script_public_key).into()) }
57 }
58}
59
60impl From<&Transaction> for protowire::TransactionMessage {
61 fn from(tx: &Transaction) -> Self {
62 Self {
63 version: tx.version as u32,
64 inputs: tx.inputs.iter().map(|input| input.into()).collect(),
65 outputs: tx.outputs.iter().map(|output| output.into()).collect(),
66 lock_time: tx.lock_time,
67 subnetwork_id: Some((&tx.subnetwork_id).into()),
68 gas: tx.gas,
69 payload: tx.payload.clone(),
70 mass: tx.mass(),
71 }
72 }
73}
74
75impl TryFrom<protowire::TransactionId> for TransactionId {
80 type Error = ConversionError;
81
82 fn try_from(value: protowire::TransactionId) -> Result<Self, Self::Error> {
83 Ok(Self::from_bytes(value.bytes.as_slice().try_into()?))
84 }
85}
86
87impl TryFrom<protowire::Outpoint> for TransactionOutpoint {
88 type Error = ConversionError;
89
90 fn try_from(item: protowire::Outpoint) -> Result<Self, Self::Error> {
91 Ok(Self::new(item.transaction_id.try_into_ex()?, item.index))
92 }
93}
94
95impl TryFrom<protowire::ScriptPublicKey> for ScriptPublicKey {
96 type Error = ConversionError;
97
98 fn try_from(value: protowire::ScriptPublicKey) -> Result<Self, Self::Error> {
99 Ok(Self::from_vec(value.version.try_into()?, value.script))
100 }
101}
102
103impl TryFrom<protowire::UtxoEntry> for UtxoEntry {
104 type Error = ConversionError;
105
106 fn try_from(value: protowire::UtxoEntry) -> Result<Self, Self::Error> {
107 Ok(Self::new(value.amount, value.script_public_key.try_into_ex()?, value.block_daa_score, value.is_coinbase))
108 }
109}
110
111impl TryFrom<protowire::OutpointAndUtxoEntryPair> for (TransactionOutpoint, UtxoEntry) {
112 type Error = ConversionError;
113
114 fn try_from(value: protowire::OutpointAndUtxoEntryPair) -> Result<Self, Self::Error> {
115 Ok((value.outpoint.try_into_ex()?, value.utxo_entry.try_into_ex()?))
116 }
117}
118
119impl TryFrom<protowire::TransactionInput> for TransactionInput {
120 type Error = ConversionError;
121
122 fn try_from(value: protowire::TransactionInput) -> Result<Self, Self::Error> {
123 Ok(Self::new(value.previous_outpoint.try_into_ex()?, value.signature_script, value.sequence, value.sig_op_count.try_into()?))
124 }
125}
126
127impl TryFrom<protowire::TransactionOutput> for TransactionOutput {
128 type Error = ConversionError;
129
130 fn try_from(output: protowire::TransactionOutput) -> Result<Self, Self::Error> {
131 Ok(Self::new(output.value, output.script_public_key.try_into_ex()?))
132 }
133}
134
135impl TryFrom<protowire::TransactionMessage> for Transaction {
136 type Error = ConversionError;
137
138 fn try_from(tx: protowire::TransactionMessage) -> Result<Self, Self::Error> {
139 let transaction = Self::new(
140 tx.version.try_into()?,
141 tx.inputs.into_iter().map(|i| i.try_into()).collect::<Result<Vec<TransactionInput>, Self::Error>>()?,
142 tx.outputs.into_iter().map(|i| i.try_into()).collect::<Result<Vec<TransactionOutput>, Self::Error>>()?,
143 tx.lock_time,
144 tx.subnetwork_id.try_into_ex()?,
145 tx.gas,
146 tx.payload,
147 );
148 transaction.set_mass(tx.mass);
149 Ok(transaction)
150 }
151}