def test_fail_missing_signature_fragment_underflow(self): """ The last transaction in the bundle is an input, and its second signature fragment is missing. """ # Remove the last input's second signature fragment, and the change # transaction. del self.bundle.transactions[-2:] for (i, txn) in enumerate(self.bundle): # type: Tuple[int, Transaction] txn.current_index = i txn.last_index = 1 # Fix bundle balance, since we removed the change transaction. self.bundle[1].value = -self.bundle[0].value validator = BundleValidator(self.bundle) self.assertFalse(validator.is_valid()) self.assertListEqual( validator.errors, [ 'Transaction 1 has invalid signature (using 1 fragments).', ], )
def test_fail_multiple_errors(self): """ The bundle has multiple problems. """ del self.bundle.transactions[2] validator = BundleValidator(self.bundle) self.assertFalse(validator.is_valid()) self.assertListEqual( validator.errors, # Note that there is no error about the missing signature # fragment for transaction 1. The bundle fails some basic # consistency checks, so we don't even bother to validate # signatures. [ 'Transaction 0 has invalid last index value ' '(expected 2, actual 3).', 'Transaction 1 has invalid last index value ' '(expected 2, actual 3).', 'Transaction 2 has invalid current index value ' '(expected 2, actual 3).', 'Transaction 2 has invalid last index value ' '(expected 2, actual 3).', ], )
def test_pass_empty(self): """ Bundle has no transactions. """ validator = BundleValidator(Bundle()) self.assertListEqual(validator.errors, []) self.assertTrue(validator.is_valid())
def test_pass_happy_path(self): """ Bundle passes validation. """ validator = BundleValidator(self.bundle) self.assertListEqual(validator.errors, []) self.assertTrue(validator.is_valid())
def test_fail_signature_invalid(self): """ One of the input signatures fails validation. """ self.bundle[2].signature_message_fragment[:-1] = b'9' validator = BundleValidator(self.bundle) self.assertFalse(validator.is_valid()) self.assertListEqual( validator.errors, [ 'Transaction 1 has invalid signature (using 2 fragments).', ], )
def test_fail_balance_negative(self): """ The bundle balance is < 0. """ self.bundle.transactions[3].value -= 1 validator = BundleValidator(self.bundle) self.assertFalse(validator.is_valid()) self.assertListEqual( validator.errors, [ 'Bundle has invalid balance (expected 0, actual -1).', ], )
def test_fail_signature_fragment_value_wrong(self): """ The second signature fragment for an input has a nonzero balance. """ self.bundle[2].value = -1 self.bundle[-1].value += 1 validator = BundleValidator(self.bundle) self.assertFalse(validator.is_valid()) self.assertListEqual( validator.errors, [ 'Transaction 2 has invalid amount (expected 0, actual -1).', ], )
def test_fail_last_index_invalid(self): """ One of the transactions has an invalid ``last_index`` value. """ self.bundle.transactions[0].last_index = 2 validator = BundleValidator(self.bundle) self.assertFalse(validator.is_valid()) self.assertListEqual( validator.errors, [ 'Transaction 0 has invalid last index value ' '(expected 3, actual 2).' ], )
def test_fail_current_index_invalid(self): """ One of the transactions has an invalid ``current_index`` value. """ self.bundle.transactions[3].current_index = 4 validator = BundleValidator(self.bundle) self.assertFalse(validator.is_valid()) self.assertListEqual( validator.errors, [ 'Transaction 3 has invalid current index value ' '(expected 3, actual 4).', ], )
def test_fail_bundle_hash_invalid(self): """ One of the transactions has an invalid ``bundle_hash`` value. """ # noinspection SpellCheckingInspection self.bundle.transactions[3].bundle_hash =\ BundleHash( b'NFDPEEZCWVYLKZGSLCQNOFUSENIXRHWWTZFBXMPS' b'QHEDFWZULBZFEOMNLRNIDQKDNNIELAOXOVMYEI9PG' ) validator = BundleValidator(self.bundle) self.assertFalse(validator.is_valid()) self.assertListEqual( validator.errors, [ 'Transaction 3 has invalid bundle hash.', ], )
def test_fail_signature_fragment_address_wrong(self): """ The second signature fragment for an input is associated with the wrong address. """ # noinspection SpellCheckingInspection self.bundle[2].address =\ Address( b'QHEDFWZULBZFEOMNLRNIDQKDNNIELAOXOVMYEI9P' b'GNFDPEEZCWVYLKZGSLCQNOFUSENIXRHWWTZFBXMPS' ) validator = BundleValidator(self.bundle) self.assertFalse(validator.is_valid()) self.assertListEqual( validator.errors, [ 'Transaction 1 has invalid signature (using 1 fragments).', ], )
gpk_result = api_3.get_private_keys(index=8, count=1, security_level=2) private_key_3 = gpk_result['keys'][0] # type: PrivateKey private_key_3.sign_input_transactions(bundle, 7) # Once we've applied the signatures, convert the Bundle back into tryte # sequences so that we can broadcast them to the tangle. signed_trytes = bundle.as_tryte_strings() """ Step 4.5 (Optional): Validate the signatures. This step is purely optional. We are including it in this example script so that you can see that the resulting signature fragments are valid. """ validator = BundleValidator(bundle) if not validator.is_valid(): raise ValueError( 'Bundle failed validation:\n{errors}'.format( errors = '\n'.join((' - ' + e) for e in validator.errors), ), ) """ Step 5: Broadcast the bundle. Note that this step works the same as any other transfer. """ api_1.send_trytes(trytes=signed_trytes, depth=3)
gpk_result = api_2.get_private_keys(index=42, count=1, security_level=3) private_key_2 = gpk_result['keys'][0] # type: PrivateKey private_key_2.sign_input_transactions(bundle, 4) gpk_result = api_3.get_private_keys(index=8, count=1, security_level=2) private_key_3 = gpk_result['keys'][0] # type: PrivateKey private_key_3.sign_input_transactions(bundle, 7) # Once we've applied the signatures, convert the Bundle back into tryte # sequences so that we can broadcast them to the tangle. signed_trytes = bundle.as_tryte_strings() """ Step 4.5 (Optional): Validate the signatures. This step is purely optional. We are including it in this example script so that you can see that the resulting signature fragments are valid. """ validator = BundleValidator(bundle) if not validator.is_valid(): raise ValueError( 'Bundle failed validation:\n{errors}'.format(errors='\n'.join( (' - ' + e) for e in validator.errors), ), ) """ Step 5: Broadcast the bundle. Note that this step works the same as any other transfer. """ api_1.send_trytes(trytes=signed_trytes, depth=3)