iota_validation/
validators.rs1use iota_conversion;
2use iota_conversion::Trinary;
3use iota_crypto::{self, Kerl, Sponge};
4use iota_model::{Signature, Transaction};
5
6use crate::Result;
7
8use super::input_validator;
9use std::convert::TryInto;
10
11pub fn is_bundle(bundle: &[Transaction]) -> Result<bool> {
13 if !input_validator::is_slice_of_transactions(bundle) {
14 return Ok(false);
15 }
16 let mut total_sum = 0;
17 let bundle_hash = &bundle[0].bundle;
18
19 let mut hash_from_txs = [0; 243];
20 let mut kerl = Kerl::default();
21 let mut signatures_to_validate: Vec<Signature> = Vec::new();
22
23 for (index, tx) in bundle.iter().enumerate() {
24 let tx_value = tx.value;
25 total_sum += tx_value;
26 if index != tx.current_index {
27 return Ok(false);
28 }
29 let tx_trytes: String = tx.try_into()?;
30 let tx_trits = (&tx_trytes[2187..2187 + 162]).trits();
31 kerl.absorb(&tx_trits)?;
32 if tx_value < 0 {
33 let this_address = &tx.address;
34 let mut new_signature = Signature::default();
35 for i in index..bundle.len() - 1 {
36 let new_tx = &bundle[i + 1];
37 if new_tx.address == *this_address && new_tx.value == 0 {
38 new_signature.add_fragment(new_tx.signature_fragments.clone());
39 }
40 }
41 signatures_to_validate.push(new_signature);
42 }
43 }
44 if total_sum != 0 {
45 return Ok(false);
46 }
47 kerl.squeeze(&mut hash_from_txs)?;
48 let bundle_from_txs = hash_from_txs.trytes()?;
49 if bundle_from_txs != *bundle_hash {
50 return Ok(false);
51 }
52 if bundle.last().unwrap().current_index != bundle.last().unwrap().last_index {
53 return Ok(false);
54 }
55 Ok(true)
66}