|
3 | 3 | unicode_literals |
4 | 4 |
|
5 | 5 | from operator import attrgetter |
6 | | -from typing import Generator, Iterable, Iterator, List, MutableSequence, \ |
7 | | - Optional, Sequence, Text, Tuple |
| 6 | +from typing import Iterable, Iterator, List, MutableSequence, \ |
| 7 | + Optional, Sequence, Text |
8 | 8 |
|
9 | 9 | from iota.codecs import TrytesDecodeError |
10 | 10 | from iota.crypto import Curl, HASH_LENGTH |
11 | | -from iota.crypto.signing import validate_signature_fragments |
12 | 11 | from iota.json import JsonSerializable |
13 | 12 | from iota.transaction.types import BundleHash, Fragment, TransactionHash, \ |
14 | 13 | TransactionTrytes |
|
17 | 16 |
|
18 | 17 | __all__ = [ |
19 | 18 | 'Bundle', |
20 | | - 'BundleValidator', |
21 | 19 | 'Transaction', |
22 | 20 | ] |
23 | 21 |
|
@@ -482,158 +480,3 @@ def group_transactions(self): |
482 | 480 | return groups |
483 | 481 |
|
484 | 482 |
|
485 | | -class BundleValidator(object): |
486 | | - """ |
487 | | - Checks a bundle and its transactions for problems. |
488 | | - """ |
489 | | - def __init__(self, bundle): |
490 | | - # type: (Bundle) -> None |
491 | | - super(BundleValidator, self).__init__() |
492 | | - |
493 | | - self.bundle = bundle |
494 | | - |
495 | | - self._errors = [] # type: Optional[List[Text]] |
496 | | - self._validator = self._create_validator() |
497 | | - |
498 | | - @property |
499 | | - def errors(self): |
500 | | - # type: () -> List[Text] |
501 | | - """ |
502 | | - Returns all errors found with the bundle. |
503 | | - """ |
504 | | - try: |
505 | | - self._errors.extend(self._validator) # type: List[Text] |
506 | | - except StopIteration: |
507 | | - pass |
508 | | - |
509 | | - return self._errors |
510 | | - |
511 | | - def is_valid(self): |
512 | | - # type: () -> bool |
513 | | - """ |
514 | | - Returns whether the bundle is valid. |
515 | | - """ |
516 | | - if not self._errors: |
517 | | - try: |
518 | | - # We only have to check for a single error to determine if the |
519 | | - # bundle is valid or not. |
520 | | - self._errors.append(next(self._validator)) |
521 | | - except StopIteration: |
522 | | - pass |
523 | | - |
524 | | - return not self._errors |
525 | | - |
526 | | - def _create_validator(self): |
527 | | - # type: () -> Generator[Text] |
528 | | - """ |
529 | | - Creates a generator that does all the work. |
530 | | - """ |
531 | | - # Group transactions by address to make it easier to iterate over |
532 | | - # inputs. |
533 | | - grouped_transactions = self.bundle.group_transactions() |
534 | | - |
535 | | - # Define a few expected values. |
536 | | - bundle_hash = self.bundle.hash |
537 | | - last_index = len(self.bundle) - 1 |
538 | | - |
539 | | - # Track a few others as we go along. |
540 | | - balance = 0 |
541 | | - |
542 | | - # Check indices and balance first. |
543 | | - # Note that we use a counter to keep track of the current index, |
544 | | - # since at this point we can't trust that the transactions have |
545 | | - # correct ``current_index`` values. |
546 | | - counter = 0 |
547 | | - for group in grouped_transactions: |
548 | | - for txn in group: |
549 | | - balance += txn.value |
550 | | - |
551 | | - if txn.bundle_hash != bundle_hash: |
552 | | - yield 'Transaction {i} has invalid bundle hash.'.format( |
553 | | - i = counter, |
554 | | - ) |
555 | | - |
556 | | - if txn.current_index != counter: |
557 | | - yield ( |
558 | | - 'Transaction {i} has invalid current index value ' |
559 | | - '(expected {i}, actual {actual}).'.format( |
560 | | - actual = txn.current_index, |
561 | | - i = counter, |
562 | | - ) |
563 | | - ) |
564 | | - |
565 | | - if txn.last_index != last_index: |
566 | | - yield ( |
567 | | - 'Transaction {i} has invalid last index value ' |
568 | | - '(expected {expected}, actual {actual}).'.format( |
569 | | - actual = txn.last_index, |
570 | | - expected = last_index, |
571 | | - i = counter, |
572 | | - ) |
573 | | - ) |
574 | | - |
575 | | - counter += 1 |
576 | | - |
577 | | - # Bundle must be balanced (spends must match inputs). |
578 | | - if balance != 0: |
579 | | - yield ( |
580 | | - 'Bundle has invalid balance (expected 0, actual {actual}).'.format( |
581 | | - actual = balance, |
582 | | - ) |
583 | | - ) |
584 | | - |
585 | | - # Signature validation is only meaningful if the transactions are |
586 | | - # otherwise valid. |
587 | | - if not self._errors: |
588 | | - for group in grouped_transactions: |
589 | | - # Signature validation only applies to inputs. |
590 | | - if group[0].value >= 0: |
591 | | - continue |
592 | | - |
593 | | - signature_valid = True |
594 | | - signature_fragments = [] |
595 | | - for j, txn in enumerate(group): # type: Tuple[int, Transaction] |
596 | | - if (j > 0) and (txn.value != 0): |
597 | | - # Input is malformed; signature fragments after the first |
598 | | - # should have zero value. |
599 | | - yield ( |
600 | | - 'Transaction {i} has invalid amount ' |
601 | | - '(expected 0, actual {actual}).'.format( |
602 | | - actual = txn.value, |
603 | | - |
604 | | - # If we get to this point, we know that the |
605 | | - # ``current_index`` value for each transaction can be |
606 | | - # trusted. |
607 | | - i = txn.current_index, |
608 | | - ) |
609 | | - ) |
610 | | - |
611 | | - # We won't be able to validate the signature, but continue |
612 | | - # anyway, so that we can check that the other transactions |
613 | | - # in the group have the correct ``value``. |
614 | | - signature_valid = False |
615 | | - continue |
616 | | - |
617 | | - signature_fragments.append(txn.signature_message_fragment) |
618 | | - |
619 | | - # After collecting the signature fragment from each transaction |
620 | | - # in the group, run it through the validator. |
621 | | - if signature_valid: |
622 | | - signature_valid = validate_signature_fragments( |
623 | | - fragments = signature_fragments, |
624 | | - hash_ = txn.bundle_hash, |
625 | | - public_key = txn.address, |
626 | | - ) |
627 | | - |
628 | | - if not signature_valid: |
629 | | - yield ( |
630 | | - 'Transaction {i} has invalid signature ' |
631 | | - '(using {fragments} fragments).'.format( |
632 | | - fragments = len(signature_fragments), |
633 | | - |
634 | | - # If we get to this point, we know that the |
635 | | - # ``current_index`` value for each transaction can be |
636 | | - # trusted. |
637 | | - i = group[0].current_index, |
638 | | - ) |
639 | | - ) |
0 commit comments