1use rand::Rng;
24use serde::{Serialize, Deserialize};
25
26use crate::validate;
27use crate::utils::*;
28use crate::schema::Schema;
29use crate::coin::{coin_validate, coin_order};
30use crate::state::State;
31use crate::error::ErrorKind;
32
33
34#[derive(Debug, PartialEq)]
36pub enum Type {
37 Transfer,
38 Fee,
39 Split,
40 Merge,
41}
42
43
44#[derive(Debug, Clone, Serialize, Deserialize)]
51pub struct Transaction {
52 pub coin: U256,
53 pub addr: U256,
54 pub sign_r: U256,
55 pub sign_s: U256,
56}
57
58
59impl Transaction {
60 pub fn new(coin: U256, addr: U256, sign_r: U256, sign_s: U256) -> Self {
62 Self { coin, addr, sign_r, sign_s }
63 }
64
65 pub fn build<R: Rng>(rng: &mut R, coin: U256, addr: U256, key: &U256,
68 counter: u64, schema: &Schema) -> Self {
69 let hash = Self::calc_msg(&coin, &addr, counter);
70 let (sign_r, sign_s) = schema.build_signature(rng, &hash, key);
71 Self::new(coin, addr, sign_r, sign_s)
72 }
73
74 pub fn get_type(&self) -> Type {
76 if self.addr == U256::from(0) {
77 Type::Fee
78 } else if self.addr == U256::from(1) {
79 Type::Split
80 } else if self.addr == U256::from(2) {
81 Type::Merge
82 } else {
83 Type::Transfer
84 }
85 }
86
87 pub fn get_msg(&self, counter: u64) -> U256 {
89 Self::calc_msg(&self.coin, &self.addr, counter)
90 }
91
92 pub fn get_hash(&self) -> U256 {
94 hash_of_u256(
95 [&self.coin, &self.addr, &self.sign_r, &self.sign_s].into_iter()
96 )
97 }
98
99 #[deprecated(since="0.1.0", note="use precalculated sender instead")]
101 pub fn get_sender(&self, state: &State, schema: &Schema) -> U256 {
102 let counter = state.get_coin_counter(&self.coin);
103 schema.extract_public(
104 &self.get_msg(counter),
105 &(self.sign_r.clone(), self.sign_s.clone())
106 )
107 }
108
109 pub fn get_order(&self, state: &State, sender: &U256) -> u64 {
111 if let Some(coin_info) = state.get_coin_info(&self.coin) {
112 coin_info.order
113 } else {
114 coin_order(&self.coin, sender)
115 }
116 }
117
118 pub fn validate_coin(&self, state: &State,
123 sender: &U256) -> UqoinResult<()> {
124 if let Some(owner) = state.get_owner(&self.coin) {
126 validate!(owner == sender, TransactionInvalidSender)?;
128 } else {
129 coin_validate(&self.coin, sender)?;
131 }
132
133 Ok(())
134 }
135
136 pub fn calc_msg(coin: &U256, addr: &U256, counter: u64) -> U256 {
138 hash_of_u256([coin, addr, &U256::from(counter)].into_iter())
139 }
140
141 pub fn calc_senders(transactions: &[Self], state: &State,
144 schema: &Schema) -> Vec<U256> {
145 transactions.iter().map(|tr| {
146 let counter = state.get_coin_counter(&tr.coin);
147 let msg = Self::calc_msg(&tr.coin, &tr.addr, counter);
148 let signature = (tr.sign_r.clone(), tr.sign_s.clone());
149 schema.extract_public(&msg, &signature)
150 }).collect::<Vec<U256>>()
151 }
152}
153
154
155#[derive(Debug, Clone)]
160pub struct Group(Vec<Transaction>);
161
162
163impl Group {
164 pub fn new(transactions: Vec<Transaction>, state: &State,
167 senders: &[U256]) -> UqoinResult<Self> {
168 Self::validate_transactions(&transactions, state, senders)?;
169 Ok(Self(transactions))
170 }
171
172 pub fn from_vec(transactions: &mut Vec<Transaction>, state: &State,
175 senders: &[U256]) -> UqoinResult<Self> {
176 if transactions.is_empty() {
177 Err(ErrorKind::TransactionEmpty.into())
179 } else {
180 let mut size = match transactions[0].get_type() {
182 Type::Split => 1,
183 Type::Merge => 3,
184 Type::Transfer => 1,
185 _ => 0,
186 };
187
188 if size == 0 {
189 Err(ErrorKind::TransactionBrokenGroup.into())
191 } else {
192 if (size < transactions.len()) &&
194 (transactions[size].get_type() == Type::Fee) {
195 size += 1;
196 }
197
198 let trs = vec_split_left(transactions, size);
200 Self::new(trs, state, &senders[..size])
201 }
202 }
203 }
204
205 pub fn transactions(&self) -> &[Transaction] {
207 &self.0
208 }
209
210 pub fn get_type(&self) -> Type {
212 self.0[0].get_type()
213 }
214
215 pub fn get_sender(&self, senders: &[U256]) -> U256 {
217 senders[0].clone()
218 }
219
220 pub fn get_fee(&self) -> Option<&Transaction> {
222 let fee_ix = match self.0[0].get_type() {
223 Type::Split => 1,
224 Type::Merge => 3,
225 Type::Transfer => 1,
226 _ => panic!("Invalid group."),
227 };
228 self.0.get(fee_ix)
229 }
230
231 pub fn get_hash(&self) -> U256 {
233 self.0[0].get_hash()
234 }
235
236 pub fn len(&self) -> usize {
238 self.0.len()
239 }
240
241 pub fn get_order(&self, state: &State, senders: &[U256]) -> u64 {
243 match self.get_type() {
244 Type::Split => self.0[0].get_order(state, &senders[0]),
245 Type::Merge => self.0[0].get_order(state, &senders[0]) + 1,
246 Type::Transfer => self.0[0].get_order(state, &senders[0]),
247 _ => panic!("Invalid transactions in the group."),
248 }
249 }
250
251 pub fn ext_size(&self) -> usize {
253 match self.get_type() {
254 Type::Split => 3,
255 Type::Merge => 1,
256 Type::Transfer => 0,
257 _ => panic!("Invalid transactions in the group."),
258 }
259 }
260
261 pub fn validate_transactions(transactions: &[Transaction], state: &State,
263 senders: &[U256]) -> UqoinResult<()> {
264 validate!(!transactions.is_empty(), TransactionEmpty)?;
266
267 validate!(check_unique(transactions.iter().map(|tr| &tr.coin)),
269 CoinNotUnique)?;
270
271 validate!(check_same(senders.iter()), TransactionInvalidSender)?;
273
274 for transaction in transactions.iter() {
276 transaction.validate_coin(state, &senders[0])?;
277 }
278
279 match transactions[0].get_type() {
281 Type::Fee => validate!(false, TransactionBrokenGroup)?,
283
284 Type::Split => {
286 if transactions.len() > 1 {
287 validate!(transactions.len() == 2, TransactionBrokenGroup)?;
288 validate!(transactions[1].get_type() == Type::Fee,
289 TransactionBrokenGroup)?;
290 }
291 },
292
293 Type::Merge => {
295 let fee_check = (transactions.len() == 3) || (
296 (transactions.len() == 4) &&
297 (transactions[3].get_type() == Type::Fee)
298 );
299
300 validate!(fee_check, TransactionBrokenGroup)?;
301
302 let type_check =
303 (transactions[1].get_type() == Type::Merge) &&
304 (transactions[2].get_type() == Type::Merge);
305
306 validate!(type_check, TransactionBrokenGroup)?;
307
308 let order0 = transactions[0].get_order(state, &senders[0]);
309 let order1 = transactions[1].get_order(state, &senders[1]);
310 let order2 = transactions[2].get_order(state, &senders[2]);
311
312 let order_check = (order1 + 1 == order0) &&
313 (order2 + 1 == order0);
314
315 validate!(order_check, TransactionBrokenGroup)?;
316 },
317
318 Type::Transfer => {
320 if transactions.len() > 1 {
321 validate!(transactions.len() == 2, TransactionBrokenGroup)?;
322 validate!(transactions[1].get_type() == Type::Fee,
323 TransactionBrokenGroup)?;
324 }
325 },
326 }
327
328 Ok(())
329 }
330}
331
332
333#[derive(Debug, Clone)]
340pub struct Ext(Vec<Transaction>);
341
342
343impl Ext {
344 pub fn new(transactions: Vec<Transaction>, state: &State,
346 senders: &[U256]) -> UqoinResult<Self> {
347 Self::validate_transactions(&transactions, state, senders)?;
348 Ok(Self(transactions))
349 }
350
351 pub fn transactions(&self) -> &[Transaction] {
353 &self.0
354 }
355
356 pub fn get_type(&self) -> Type {
358 match self.0.len() {
359 0 => Type::Transfer,
360 1 => Type::Merge,
361 3 => Type::Split,
362 _ => panic!("Invalid size of extension."),
363 }
364 }
365
366 pub fn get_sender(&self, senders: &[U256]) -> Option<U256> {
368 if self.0.is_empty() {
369 None
370 } else {
371 Some(senders[0].clone())
372 }
373 }
374
375 pub fn len(&self) -> usize {
377 self.0.len()
378 }
379
380 pub fn get_order(&self, state: &State, senders: &[U256]) -> u64 {
382 match self.0.len() {
383 0 => 0,
384 1 => self.0[0].get_order(state, &senders[0]),
385 3 => &self.0[0].get_order(state, &senders[0]) + 1,
386 _ => panic!("Invalid transactions in the group."),
387 }
388 }
389
390 pub fn validate_transactions(transactions: &[Transaction], state: &State,
392 senders: &[U256]) -> UqoinResult<()> {
393 validate!(check_unique(transactions.iter().map(|tr| &tr.coin)),
395 CoinNotUnique)?;
396
397 validate!(check_same(senders.iter()), TransactionInvalidSender)?;
399
400 for transaction in transactions.iter() {
402 transaction.validate_coin(state, &senders[0])?;
403 }
404
405 match transactions.len() {
407 0 => {},
409
410 1 => validate!(transactions[0].get_type() == Type::Transfer,
412 TransactionBrokenExt)?,
413
414 3 => {
416 let addr = &transactions[0].addr;
418
419 let type_check = transactions.iter()
421 .all(|tr| tr.get_type() == Type::Transfer);
422
423 validate!(type_check, TransactionBrokenExt)?;
424
425 let addr_check =
427 (&transactions[1].addr == addr) &&
428 (&transactions[2].addr == addr);
429
430 validate!(addr_check, TransactionBrokenExt)?;
431
432 let order0 = transactions[0].get_order(state, &senders[0]);
434 let order1 = transactions[1].get_order(state, &senders[1]);
435 let order2 = transactions[2].get_order(state, &senders[2]);
436
437 let order_check = (order1 + 1 == order0) &&
438 (order2 + 1 == order0);
439
440 validate!(order_check, TransactionBrokenExt)?;
441 },
442
443 _ => panic!("Invalid size of extension."),
445 }
446
447 Ok(())
448 }
449}
450
451
452pub fn group_transactions(mut transactions: Vec<Transaction>, state: &State,
456 senders: &[U256]) ->
457 impl Iterator<Item = (usize, Group, Ext)> {
458 let mut offset = 0;
459 std::iter::from_fn(move || {
460 if let Ok(group) = Group::from_vec(&mut transactions, state,
461 &senders[offset..]) {
462 let group_size = group.len();
463 let ext_size = group.ext_size();
464 let ext_trs = vec_split_left(&mut transactions, ext_size);
465 let ext_senders = &senders[
466 offset + group_size .. offset + group_size + ext_size
467 ];
468
469 if let Ok(ext) = Ext::new(ext_trs, state, ext_senders) {
470 let res = (offset, group, ext);
471 offset += group_size + ext_size;
472 Some(res)
473 } else {
474 None
475 }
476 } else {
477 None
478 }
479 })
480}