1use crate::address::{Address, AddressError};
2use crate::amount::AmountError;
3use crate::extended_private_key::ExtendedPrivateKeyError;
4use crate::format::Format;
5use crate::private_key::{PrivateKey, PrivateKeyError};
6use crate::public_key::PublicKey;
7
8use rlp;
9use std::{
10 fmt::{Debug, Display},
11 hash::Hash,
12};
13
14pub trait TransactionId: Clone + Debug + Display + Send + Sync + 'static + Eq + Ord + Sized + Hash {}
16
17pub trait Transaction: Clone + Send + Sync + 'static {
19 type Address: Address;
20 type Format: Format;
21 type PrivateKey: PrivateKey;
22 type PublicKey: PublicKey;
23 type TransactionId: TransactionId;
24 type TransactionParameters;
25
26 fn new(parameters: &Self::TransactionParameters) -> Result<Self, TransactionError>;
28
29 fn sign(&self, private_key: &Self::PrivateKey) -> Result<Self, TransactionError>;
31
32 fn from_transaction_bytes(transaction: &Vec<u8>) -> Result<Self, TransactionError>;
34
35 fn to_transaction_bytes(&self) -> Result<Vec<u8>, TransactionError>;
37
38 fn to_transaction_id(&self) -> Result<Self::TransactionId, TransactionError>;
40}
41
42#[derive(Debug, Fail)]
43pub enum TransactionError {
44 #[fail(display = "{}", _0)]
45 AddressError(AddressError),
46
47 #[fail(display = "{}", _0)]
48 AmountError(AmountError),
49
50 #[fail(display = "witnesses have a conflicting anchor")]
51 ConflictingWitnessAnchors(),
52
53 #[fail(display = "{}: {}", _0, _1)]
54 Crate(&'static str, String),
55
56 #[fail(display = "{}", _0)]
57 ExtendedPrivateKeyError(ExtendedPrivateKeyError),
58
59 #[fail(display = "Failed note decryption for enc_cyphertext: {}", _0)]
60 FailedNoteDecryption(String),
61
62 #[fail(display = "invalid binding signature for the transaction")]
63 InvalidBindingSig(),
64
65 #[fail(display = "invalid chain id {:?}", _0)]
66 InvalidChainId(u8),
67
68 #[fail(display = "invalid ephemeral key {}", _0)]
69 InvalidEphemeralKey(String),
70
71 #[fail(display = "insufficient information to craft transaction. missing: {}", _0)]
72 InvalidInputs(String),
73
74 #[fail(display = "invalid output address: {}", _0)]
75 InvalidOutputAddress(String),
76
77 #[fail(display = "invalid ouptut description for address: {}", _0)]
78 InvalidOutputDescription(String),
79
80 #[fail(display = "invalid transaction RLP length: expected - 9, found - {:?}", _0)]
81 InvalidRlpLength(usize),
82
83 #[fail(display = "invalid script pub key for format: {}", _0)]
84 InvalidScriptPubKey(String),
85
86 #[fail(display = "invalid segwit flag: {:?}", _0)]
87 InvalidSegwitFlag(usize),
88
89 #[fail(display = "invalid spend description for address")]
90 InvalidSpendDescription,
91
92 #[fail(display = "invalid transaction id {:?}", _0)]
93 InvalidTransactionId(usize),
94
95 #[fail(display = "invalid transaction - either both sender and signature should be present, or neither")]
96 InvalidTransactionState,
97
98 #[fail(display = "invalid variable size integer: {:?}", _0)]
99 InvalidVariableSizeInteger(usize),
100
101 #[fail(display = "{}", _0)]
102 Message(String),
103
104 #[fail(display = "missing diversifier, check that the address is a Sapling address")]
105 MissingDiversifier,
106
107 #[fail(display = "missing outpoint address")]
108 MissingOutpointAddress,
109
110 #[fail(display = "missing outpoint amount")]
111 MissingOutpointAmount,
112
113 #[fail(display = "missing outpoint script public key")]
114 MissingOutpointScriptPublicKey,
115
116 #[fail(display = "missing output parameters")]
117 MissingOutputParameters,
118
119 #[fail(display = "missing spend description")]
120 MissingSpendDescription,
121
122 #[fail(display = "missing spend parameters")]
123 MissingSpendParameters,
124
125 #[fail(display = "Null Error {:?}", _0)]
126 NullError(()),
127
128 #[fail(display = "{}", _0)]
129 PrivateKeyError(PrivateKeyError),
130
131 #[fail(display = "Joinsplits are not supported")]
132 UnsupportedJoinsplits,
133
134 #[fail(display = "unsupported preimage operation on address format of {}", _0)]
135 UnsupportedPreimage(String),
136}
137
138impl From<&'static str> for TransactionError {
139 fn from(msg: &'static str) -> Self {
140 TransactionError::Message(msg.into())
141 }
142}
143
144impl From<()> for TransactionError {
145 fn from(error: ()) -> Self {
146 TransactionError::NullError(error)
147 }
148}
149
150impl From<AddressError> for TransactionError {
151 fn from(error: AddressError) -> Self {
152 TransactionError::AddressError(error)
153 }
154}
155
156impl From<AmountError> for TransactionError {
157 fn from(error: AmountError) -> Self {
158 TransactionError::AmountError(error)
159 }
160}
161
162impl From<base58::FromBase58Error> for TransactionError {
163 fn from(error: base58::FromBase58Error) -> Self {
164 TransactionError::Crate("base58", format!("{:?}", error))
165 }
166}
167
168impl From<base58_monero::base58::Error> for TransactionError {
169 fn from(error: base58_monero::base58::Error) -> Self {
170 TransactionError::Crate("base58_monero", format!("{:?}", error))
171 }
172}
173
174impl From<bech32::Error> for TransactionError {
175 fn from(error: bech32::Error) -> Self {
176 TransactionError::Crate("bech32", format!("{:?}", error))
177 }
178}
179
180impl From<ExtendedPrivateKeyError> for TransactionError {
181 fn from(error: ExtendedPrivateKeyError) -> Self {
182 TransactionError::ExtendedPrivateKeyError(error)
183 }
184}
185
186impl From<ff::PrimeFieldDecodingError> for TransactionError {
187 fn from(error: ff::PrimeFieldDecodingError) -> Self {
188 TransactionError::Crate("ff", format!("{:?}", error))
189 }
190}
191
192impl From<hex::FromHexError> for TransactionError {
193 fn from(error: hex::FromHexError) -> Self {
194 TransactionError::Crate("hex", format!("{:?}", error))
195 }
196}
197
198impl From<PrivateKeyError> for TransactionError {
199 fn from(error: PrivateKeyError) -> Self {
200 TransactionError::PrivateKeyError(error)
201 }
202}
203
204impl From<rlp::DecoderError> for TransactionError {
205 fn from(error: rlp::DecoderError) -> Self {
206 TransactionError::Crate("rlp", format!("{:?}", error))
207 }
208}
209
210impl From<secp256k1::Error> for TransactionError {
211 fn from(error: secp256k1::Error) -> Self {
212 TransactionError::Crate("secp256k1", format!("{:?}", error))
213 }
214}
215
216impl From<serde_json::error::Error> for TransactionError {
217 fn from(error: serde_json::error::Error) -> Self {
218 TransactionError::Crate("serde_json", format!("{:?}", error))
219 }
220}
221
222impl From<std::io::Error> for TransactionError {
223 fn from(error: std::io::Error) -> Self {
224 TransactionError::Crate("std::io", format!("{:?}", error))
225 }
226}
227
228impl From<std::str::ParseBoolError> for TransactionError {
229 fn from(error: std::str::ParseBoolError) -> Self {
230 TransactionError::Crate("std::str", format!("{:?}", error))
231 }
232}
233
234impl From<std::num::ParseIntError> for TransactionError {
235 fn from(error: std::num::ParseIntError) -> Self {
236 TransactionError::Crate("std::num", format!("{:?}", error))
237 }
238}
239
240impl From<uint::FromDecStrErr> for TransactionError {
241 fn from(error: uint::FromDecStrErr) -> Self {
242 TransactionError::Crate("uint", format!("{:?}", error))
243 }
244}